拓扑排序算法

news2024/11/26 10:28:01

背景

拓扑排序是啥意思?

拓扑排序是指: 将有向无环图(DAG)展开为一维的执行序列。DAG顾名思义就是有方向的图,下面这张图就简单说明了啥是有向无环图。一般人可能用到这个算法的情况不多,但是刷leetcode的课程表问题肯定遇到过,其次搞人工智能的同学静态图执行顺序也不应该陌生。
在这里插入图片描述

算法流程

先简单分析,从上面的图可以知道,要执行3节点,依赖0,1, 所以需要先执行完0,1。依次类推可以有一下的执行顺序:

  • [0,1,2,3,4,5]
  • [0,2,1,3,4,5]
  • [0,1,2,4,3,5]

此外还有很多排序方式,可见拓扑图的排序有很多选择,只要满足执行依赖要求都是可行的拓扑排序。接下来正式分析一下算法流程:

  1. 入度数组:这里需要增加两个概念:入度和出度,入度是指该节点有几个输入,出度是指该节点有几个输出。根据上面的铺垫可以很容易想到,入度为0的节点当下是可以执行的,毕竟他没有什么依赖。所以我们可以搞一个入度数组,记录每个节点的入度个数,如果当下的入度个数为0,那么该节点就是当下可以执行。
  2. 邻接表:根据上面的图我们知道,当0,1节点执行完后,节点2的入度也就变成0了,所以每个节点执行完,都应该更新一波入度数组,那么怎么更新了?这就依赖邻接表来完成,这里邻接表是一个map<node, vector<node>>,其中key是节点名node,value是依赖该key_node的节点们,也就是说把key_node作为入度之一的节点。

代码

//入度数组
vector<int> TopologyDfsSort(graph)
{
	vector<int> in_degree(n,0);
	init(in_degree, graph);
	//邻接表
	unordered_map<int, vector<int>> map;
	init(map, graph);
	//当下可执行的节点集合
	vector<int> res;
	// 每次跟新的队列
	queue<int> q;
	for(int i=0; i<in_degree.size(); i++)
	{
		if(in_degree[i]==0) 
		{
			q.push(i);//入度为0的都可以执行
			res.push(i);//入度为0的都可以执行
		}
	}
	//更新
	while(!q.empty())
	{
		//一轮执行size个节点,q中是表示该轮可以执行的节点
		int size = q.size();
		for(int i=0; i<size; i++)
		{
			int exec_node = q.front();
			q.pop();
			//一旦exec_node执行,那么依赖exec_node的node的入度值都可以减一
			vector<int> nodes = map[exec_node];
			for(auto id:nodes)
			{
				in_degree[id]--;
				if(in_degree[id]==0)//如果入度为0,那么就可以进入下一轮执行
				{
					q.push(id);//入度为0的都可以执行
					res.push(id);//入度为0的都可以执行
				}
			}
		}
	}
	return res;
}

实战

可以参考paddlepaddle源码中的实现:
paddle/fluid/framework/ir/graph_helper.cc:266L

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/50350.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ShardingJdbcⅡ

序言 在前文的基础上继续梳理一下分片的相关信息.基于shardingsphere-sharding-api:jar:5.2.1的源码,感觉ShardingJdbc的版本变动频繁且比较大cuiyaonan2000163.com 切入口是如下的内容,吐槽下官网的API文档不太够能把事情说清楚: 分片算法 从上面的自定义分片的可选类型我们…

我有两个列表,现在需要找出两个列表中的不同元素,怎么做?

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注回复“书籍”即可获赠Python从入门到进阶共10本电子书今日鸡汤秦时明月汉时关&#xff0c;万里长征人未还。大家好&#xff0c;我是皮皮。一、前言前几天在帮助粉丝解决问题的时候&#xff0c;遇到一个简单的小需求&#…

[附源码]Python计算机毕业设计Django的物品交换平台

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【Pandas数据处理100例】(八十五):Pandas将DataFrame数据转化成字典数据

前言 大家好,我是阿光。 本专栏整理了《Pandas数据分析处理》,内包含了各种常见的数据处理,以及Pandas内置函数的使用方法,帮助我们快速便捷的处理表格数据。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmPandas版本:1.3.5N…

git push出现git@github.com: Permission denied (publickey) 解决办法

故障现象 ➜ LKExtentionKit git:(master) ✗ git push --set-upstream origin master gitgithub.com: Permission denied (publickey). 错误&#xff1a;无法读取远程仓库。请确认您有正确的访问权限并且仓库存在。 解决办法 第1步,验证邮箱与GitHub注册时输入的是否一致 …

计算机网络(详解)

文章目录一&#xff0c;计算机网络⑴ 局域网&#xff08;LAN&#xff09;1) 环状拓扑结构2) 星型拓扑结构3) 总线拓扑结构⑵ 城域网&#xff08;MAN&#xff09;⑶ 广域网&#xff08;WAN&#xff09;二&#xff0c;互联网⑴ 互联网是一种计算机网络⑵ 互联网的工作模式⑶ 互联…

Leetcode 907.子数组的最小值之和(中等)

一、题目 1、题目描述 给定一个整数数组 arr&#xff0c;找到 min(b) 的总和&#xff0c;其中 b 的范围为 arr 的每个&#xff08;连续&#xff09;子数组。 由于答案可能很大&#xff0c;因此 返回答案模 10^9 7 。 示例1&#xff1a; 输入&#xff1a;arr [3,1,2,4] 输…

【Paper】2022_离散时间多智能体系统编队-包围控制研究_李博凡

离散时间多智能体系统编队-包围控制研究_李博凡 文章目录第四章 基于间歇控制的离散时间多智能体系统编队-包围控制4.1 引言4.2 基于状态反馈的离散时间间歇多智能体系统编队-包围控制4.2.1 模型描述4.2.2 稳定性分析4.3 基于观测器的离散时间间歇多智能体系统编队-包围控制4.3…

2022最全Hbuilder打包成苹果IOS-App的详解

本文相关主要记录一下使用Hbuilder打包成苹果IOS-App的详细步骤。 介绍一下个人开发者账号&#xff1a; 再说下什么是免费的苹果开发者账号&#xff0c;就是你没交688年费的就是免费账号&#xff0c;如果你想变成付费开发者账号&#xff0c;提交申请付费就行&#xff0c;账号都…

qt中Qtcpserver服务端_qt websocket

0.前言 本文主要讲解 Qt TCP 相关接口的基本应用&#xff0c;一些实践相关的后面会单独写。 TCP 协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP 通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。 TCP 通过三次握手来…

Feign的使用

1、Feigin接口&#xff1a; ProductClientService import com.mengxuegu.springcloud.entities.Product; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.anno…

SIMetrix导入MOS管SPICE参数进行仿真的快速方法

问题的提出 在采用SIMetrix 8.3软件进行E类放大器的仿真过程中&#xff0c;用到了NEXPERIA公司的NMOS管器件PMH550UNE, 但在SIMetrix 8.3的库中没有该器件&#xff0c;因此需要导入第三方库文件. 通常的办法是从生产该器件的公司网站上下载器件库文件&#xff0c;导入到SIMet…

MKS上游和下游集成式压力控制器的技术分析及其替代解决方案

摘要&#xff1a;目前的MKS系列集成式压力控制器本质上是一种流量调节和测量装置&#xff0c;无法直接用来进行准确的压力控制&#xff0c;而且MKS压力控制器还存在测量精度不高、压力控制范围有限和对工作介质洁净度要求很高的不足。为此&#xff0c;为了弥补这些不足&#xf…

Java 并发编程之ConcurrentHashMap源码详解

Java 并发编程之ConcurrentHashMap原理详解 文章目录Java 并发编程之ConcurrentHashMap原理详解原理剖析源码剖析一、构造方法分析二、初始化三、put()实现分析四、扩容原理剖析 HashMap通常的实现方式是“数组链表”&#xff0c;这种方式被称为“拉链法”。 ConcurrentHashMa…

K_A08_001 基于 STM32等单片机驱动L298N模块按键控制直流电机启停正反转加减速

目录 一、资源说明 二、基本参数 1、参数 2、引脚说明 三、驱动说明 L298N模块驱动时序 对应程序: ENA ENB输出PWM 四、部分代码说明 接线说明 1、STC89C52RCL298N模块 2、STM32F103C8T6L298N模块 五、基础知识学习与相关资料下载 六、视频效果展示与程序资料获取 七、项…

宇视雷视工勘指导(卡口电警篇)

雷视工勘指导&#xff08;卡口电警篇&#xff09; 卡口和电子警察具备车辆信息采集、违法驾驶行为检测等功能&#xff0c;是城市道路交通治理的利器。为了提升现场工勘效率并保障工勘的质量&#xff0c;本次为大家介绍一款宇视的前端工勘神器——《宇视智能交通工勘计算表》&a…

SpringMVC-全面详解(学习总结---从入门到深化)

目录 SpringMVC简介 MVC模型 SpringMVC SpringMVC入门案例 SpringMVC执行流程 SpringMVC的组件 组件的工作流程 SpringMVC参数获取_封装为简单数据类型 SpringMVC参数获取_封装为对象类型 封装单个对象 封装关联对象 SpringMVC参数获取_封装为集合类型 封装为Lis…

Qt报错总结

转载 Qt报错 widget.obj的问题 遇到这种情况可能是链接出错造成的&#xff0c;所以需要首选就是需要将生成的bulid文件进行删除&#xff0c;然后运行&#xff0c;基本可以了 补充知识&#xff1a; QtCreator中qmake、构建、运行、清理等区别与联系 qt执行流程&#xff1a;qma…

模式也能开盲盒,”盲返“模式带动电商平台共享经济

今年元月份&#xff0c;国务院也是提出消费返利、消费优惠、利润分享属于电商平台共享经济的促销模式&#xff0c;属于合法合规的新业态经济以及新零售重大变革的突破&#xff0c;全民参与共同富裕。 而最近市场上出了个很火的电商模式——消费盲返&#xff0c;是一个针对每个…

MacBook Pro 耗电严重的终极解决办法2022年

背景&#xff1a; 最近在用mac时发现一个问题&#xff0c;合上盖子之后&#xff0c;明天打开&#xff0c;没有插电源的情况下&#xff0c;就会没电&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;非常影响使用&#xff0c;最后才发现是…