对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序.

线性结构概念

总的来说,“线性结构”是一个有序数据元素的集合 线性结构满足以下特点:

  1. 集合中必存在唯一“第一个元素”;
  2. 集合中必存在唯一“最后一个元素”;
  3. 除了最后一个元素,所有元素均有唯一“后继结点”;
  4. 除了第一个元素,所有元素均有唯一“前趋结点”

和我们abp Module很像,第一个加载模块永远是其ABP核心模块,最后一个模块永远是我们的启动模块

举例

1.大学课程排序
大学课程的学习是有先后顺序的,C语言是基础,数据结构依赖于C语言,其它课程也有类似依赖关系。这样的一个课程安排是怎么实现的呢?

2.VS项目编译顺序
假设VS中有三个项目A,B,C,它们的关系如下。VS编译器是如何判断三个项目的编译顺序的呢?
A->B->C A引用B B引用C
A->B->C->A 提示循环引用

ABP的Module

ABP中的模块也是如此,不可循环引用相互依赖A->B B->A X
前面说到ABP中的第一个模块和最后一个模块是确定的。
呢么中间的是怎么排序的呢。其实用的是拓扑算法

从图中可以得知:
1.A模块是最核心的,不依赖于其他任何模块
2.D依赖E和B,E依赖B和C,B依赖C和A,C依赖A
那么根据拓扑排序,应该如何排序呢?
1.从图中找一个没有前驱指向它的顶点
2.删除该顶点.以及该顶点的前驱
3.重复步骤 1 and 2 ,直到图中顶点为空 或者 找不到步骤1中这样的顶点 为止.
排序如下:

结果就是D->E->B->C->A 排完之后正好对应D依赖E和B,E依赖B和C,B依赖C和A,C依赖A
这个顺序在ABP的模块这看来是行不通的,需要在反转一次,最先加载A,才行。

C#实现深度优先搜索

有这样一个DAG图

如果对它进行排序的话,其实过程是这样的.
图中,顶点A是没有指向它的前驱的,所以从它开始访问

1.访问 A
2.访问 B
3.访问 C
在访问了 B 后应该是访问 B 的另外一个顶点,这里可以是随机的也可以是有序的,具体取决于你存储的序列顺序,这里先访问 C 。
4.访问 E
5.访问 D
这里访问 D 是因为 B 已经被访问过了,所以访问顶点 D 。
6.访问 F
因为顶点 C 已经被访问过,所以应该回溯访问顶点 B 的另一个有向边指向的顶点 F 。
7.访问 G
那么代码应该如何写呢?
source:需要排序的集合
getDepends:一个func委托,用于获取当前模块依赖的其他模块
方法内部维护了一个字典对象Visited 用于存储已经访问过的模块,key表示模块,value是一个bool,true时表示正在处理,false表示以及处理完成,
处理完成的模块会加入到sorted集合中

static List<T> MySort<T>(IEnumerable<T> source, Func<T, IEnumerable<T>> getDepends)
{// 访问过的路径Dictionary<T, bool> visited = new Dictionary<T, bool>();// 已经排过序的List<T> sorted = new List<T>();foreach (var item in source){Visit<T>(item, getDepends, visited, sorted);}return sorted;
}static void Visit<T>(T item, Func<T, IEnumerable<T>> getDepends, Dictionary<T, bool> visited, List<T> sorted)
{//已经访问过了if (visited.ContainsKey(item)){bool isVisit = visited[item];if (isVisit == true){throw new Exception("循环引用");}}//未访问else{visited.Add(item, true);//true :正在访问 false:访问完成//获取所有依赖var depends = getDepends(item);foreach (var depend in depends){Visit(depend, getDepends, visited, sorted);}//访问完成visited[item] = false;sorted.Add(item);}}

完整demo github

转载于:https://www.cnblogs.com/zzqvq/p/10260397.html

C#实现有向无环图(DAG)拓扑排序相关推荐

  1. 有向无环图DAG 拓扑排序 代码解释

    目录: DAG定义 举例描述 实际运用 算法描述 算法实战 算法可视化 定义 在图论中,由一个有向无环图的顶点组成的序列,当且仅当满足下列条件时,称为该图的一个拓扑排序(英语:Topological ...

  2. 有向无环图(DAG)拓扑排序的两种方法

    如下图的DAG: 第一种: (1)从AOV网中选择一个没有前驱的顶点并且输出它: (2)从AOV网中删除该顶点,并且上去所有该顶点为尾的弧: (3)重复上述两步,直到全部顶点都被输出,或者AOV网中不 ...

  3. 【图论】有向无环图的拓扑排序

    1. 引言 有向无环图(Directed Acyclic Graph, DAG)是有向图的一种,字面意思的理解就是图中没有环.常常被用来表示事件之间的驱动依赖关系,管理任务之间的调度.拓扑排序是对DA ...

  4. 数据结构-考研难点代码突破 (C++实现有向无环图的拓扑排序)

    文章目录 1. AOV网 2. 拓扑排序 C++代码 1. AOV网 AOV网∶若用DAG 图(有向无环图)表示一个工程,其顶点表示活动,用有向边<Vi,Vj>表示活动 Vi必须先于活动V ...

  5. 判定有向无环图 (拓扑排序)

    问题描述: 给出一张有向图,问它是否存在环. 解题思路: 这里可以用到拓扑排序. 拓扑排序的定义 拓扑排序应用于有向无环图之中,排序完以后会出现这样的性质:对于一个点p,只对排序位置在它之后的点有边. ...

  6. 带你了解有向无环图和拓扑排序

    写在前面 如果觉得有所收获,记得点个关注和点个赞,感谢支持. 今天遇到有向无环图的一些问题,感觉挺有意思的,而且这些问题的思路特点都差不多,所以想着记录一下.在图论中,如果一个有向图无法从某个顶点出发 ...

  7. 有向无环图的拓扑排序

    拓扑排序 对于一个有向无环图,我们可以这样确定一个图中顶点的顺序:  对于所有的u.v,若存在有向路径u-->v,则在最后的顶点排序中u就位于v之前.这样确定的顺序就是一个图的拓扑排序.     ...

  8. 有向无环图的拓扑排序 关键路径

    拓扑排序:在不违背先决条件的基础上将有向无环图排成线性序列 - 排序结果不唯一 - 用一维数组Indegree存储各顶点的入度 - 采用邻接表与队列 bool TopSort(LGraph Graph ...

  9. 后端 绘制有向无环图(DAG图)

    因为公司的某个系统比较古老,里面的 job 的管理几乎都是直接通过操作数据库来实现的,对于一般的操作还可以忍受,但是每次想知道 job 之间的依赖关系的时候,就会相当难受,于是便脑袋很抽地一定要写一个 ...

最新文章

  1. mysql平均锁_MySQL锁情况分析
  2. 饶毅:脑、物理、化学、 生物、心理认知的交叉研究
  3. hdu2594 简单KMP
  4. 阿里巴巴拿下奥运顶级赞助商
  5. ES6新特性之解构表达式
  6. C语言家谱管理程序,课内资源 - 基于C语言实现的家谱管理系统
  7. 依据地图上的经纬度坐标计算某个点到多边形各边的距离
  8. 哈工大大数据实验_科研常用 | 实验大数据分析方法
  9. JVM中的五大内存区域划分详解
  10. java 注解入门 简书_Java基础-注解
  11. 77-CCI,Commodity Channel Index,商品通道指标.(2015.7.1)
  12. SSM框架Web程序的流程(Spring SpringMVC Mybatis)
  13. STL之容器——介绍
  14. CKEditor富文本编辑器使用
  15. IE 7打开网页慢解决方法
  16. 关于门控时钟的毛刺解决
  17. 输入年月日实现计算这是一年的第几天
  18. 全球与中国连续光纤激光器市场现状及未来发展趋势
  19. 用python画带有正负值的条形图
  20. 商务呈现之客户满意度

热门文章

  1. Spring Boot整合Spring Data JPA操作数据
  2. Git 常用操作(2)- 创建标签
  3. 顺时针打印矩阵 python
  4. Linux下 C语言统计时间差
  5. Python关于%matplotlib inline
  6. Apache POI:解决数据库和Excel之间相互转换的烦恼~
  7. CPU三级缓存技术解析
  8. Tengine Framework基础
  9. 智能物联网(AIoT,2020年)(下)
  10. 客快物流大数据项目(五十二):根据数据库表及字段创建公共模块