拓扑排序(一)
作者:追风剑情 发布于:2015-12-6 19:34 分类:Algorithms
拓扑排序与AOV、AOE网主要用来处理工程管理的。
在图论中,一个有向无环图的所有顶点可以排成一个线性序列,当这个线性序列满足以下条件时,称该序列为一个满足图的拓扑次序(topological order)的序列。
(1)图中的每个顶点在序列中只出现一次;
(2)对于图中任意一条有向边(u, v),在该序列中顶点u一定位于顶点v之前。
这样的序列也被称为拓扑序列,对有向图的所有顶点排序,获得拓扑序列的过程就是有向图的拓扑排序(topological sorting)。拓扑排序并不仅仅用于有向图,它是一种利用数据元素中某个属性的偏序关系得到数据元素的全排序序列的方法。
拓扑排序的基本过程:
(1) 从有向图中选择一个没有前驱(入度为0)的顶点,输出这个顶点。
(2) 从有向图中删除该顶点,同时删除由该顶点发出的所有有向边。
重复上述步骤(1)和(2),直到图中不再有入度为0的顶点为止。此时,如果所有的顶点都已经输出,则顺序输出的顶点序列就是一个拓扑序列,如果图中还有未输出的顶点,但是入度都不为0,则说明有向图中存在环路,不能进行拓扑排序。
拓扑排序的现实意义在于,如果按照拓扑序列中的顶点次序安排活动,则在每一项活动开始的时候,能够保证它所依赖的所有前驱活动都已经完成,从而使得整个工程可以顺利进行,不出现冲突。需要注意的是,对于一个有向无环图来说,有时候不只一个有序的拓扑序列。
示例
工程活动关系图
代码
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace TopSortTest
- {
- class Program
- {
- static void Main(string[] args)
- {
- //测试工程活动拓扑排序
- Activity activity = new Activity();
- activity.InitGraph();
- activity.TopSort();
- Console.Read();
- }
- }
- // 活动
- class Activity
- {
- Graph graph;
- PriorityQueue queue;
- // 初始化工程活动
- public void InitGraph()
- {
- queue = new PriorityQueue();
- //根据工程活动关系表构造有向图 (采用AOV网 + 邻接表)
- graph = new Graph();
- graph.vertexs = new VertexNode[9];
- int[] days = new int[] { 8, 5, 6, 4, 7, 7, 4, 3, 4 };
- int[] inCount = new int[] { 0, 0, 2, 1, 1, 2, 1, 1, 2 };
- List<int[]> adjacentNode = new List<int[]>();
- adjacentNode.Add( new int[] { 6, 2 } );
- adjacentNode.Add( new int[] { 4, 2 } );
- adjacentNode.Add( new int[] { 3 } );
- adjacentNode.Add( new int[] { 5, 8 } );
- adjacentNode.Add( new int[] { 5 } );
- adjacentNode.Add( null );
- adjacentNode.Add( new int[] { 7 } );
- adjacentNode.Add( new int[] { 8 } );
- adjacentNode.Add( null );
- for (int i = 0; i < graph.vertexs.Length; i++)
- {
- VertexNode v = new VertexNode();
- graph.vertexs[i] = v;
- v.name = "P" + i;
- v.days = days[i];
- v.inCount = inCount[i];
- v.adjacentNode = adjacentNode[i];
- //活动最早开始时间的自动计算算法以后再讲,这里暂时随便赋个值。
- v.sTime = new Random().Next(100);
- }
- }
- // 对活动有向图进行拓扑排序
- public bool TopSort()
- {
- List<VertexNode> sortedNode = new List<VertexNode>();
- //所有入度为0的活动进队列
- for (int i = 0; i < graph.vertexs.Length; i++)
- {
- if (graph.vertexs[i].inCount == 0)
- queue.Enqueue(graph.vertexs[i]);
- }
- while (queue.Count > 0)
- {
- VertexNode node = queue.Dequeue();
- sortedNode.Add(node);
- if (null == node.adjacentNode)
- continue;
- //遍历节点node的所有邻接点,将表示有向边的inCount值减1
- for (int j = 0; j < node.adjacentNode.Length; j++)
- {
- int adjNode = node.adjacentNode[j];
- graph.vertexs[adjNode].inCount--;
- //如果inCount值为0,则该节点入队列
- if (graph.vertexs[adjNode].inCount == 0)
- queue.Enqueue(graph.vertexs[adjNode]);
- }
- }
- //如果有向图存在环路
- if (sortedNode.Count != graph.vertexs.Length)
- {
- Console.WriteLine("有向图存在环路,活动无法顺利完成。");
- return false;
- }
- //输出
- Console.Write("拓扑排序: ");
- for (int i = 0; i < sortedNode.Count; i++)
- {
- Console.Write(sortedNode[i].name + " ");
- }
- return true;
- }
- }
- // 活动顶点数据结构
- class VertexNode
- {
- public string name;//活动名称
- public int days; //完成活动所需时间
- public int sTime; //活动最早开始时间
- public int inCount;//活动的前驱结点个数
- public int[] adjacentNode;//相邻活动列表(节点索引)
- }
- // 活动图
- class Graph
- {
- public VertexNode[] vertexs;//图的顶点列表
- }
- // 优先级队列
- class PriorityQueue
- {
- private List<VertexNode> list = new List<VertexNode>();
- public int Count
- {
- get
- {
- return list.Count;
- }
- }
- public void Enqueue(VertexNode node)
- {
- Console.WriteLine("进队列: "+node.name);
- list.Add(node);
- list.Sort(Comparison);
- }
- public VertexNode Dequeue()
- {
- VertexNode node = null;
- if (list.Count > 0)
- {
- node = list[0];
- list.RemoveAt(0);
- }
- return node;
- }
- //按活动最早开始时间排序
- int Comparison(VertexNode a, VertexNode b)
- {
- if (a.sTime > b.sTime)
- return 1;
- else if (a.sTime == b.sTime)
- return 0;
- return -1;
- }
- }
- }
运行结果:
标签: Algorithms
日历
最新文章
随机文章
热门文章
分类
存档
- 2025年3月(4)
- 2025年2月(3)
- 2025年1月(1)
- 2024年12月(5)
- 2024年11月(5)
- 2024年10月(5)
- 2024年9月(3)
- 2024年8月(3)
- 2024年7月(11)
- 2024年6月(3)
- 2024年5月(9)
- 2024年4月(10)
- 2024年3月(11)
- 2024年2月(24)
- 2024年1月(12)
- 2023年12月(3)
- 2023年11月(9)
- 2023年10月(7)
- 2023年9月(2)
- 2023年8月(7)
- 2023年7月(9)
- 2023年6月(6)
- 2023年5月(7)
- 2023年4月(11)
- 2023年3月(6)
- 2023年2月(11)
- 2023年1月(8)
- 2022年12月(2)
- 2022年11月(4)
- 2022年10月(10)
- 2022年9月(2)
- 2022年8月(13)
- 2022年7月(7)
- 2022年6月(11)
- 2022年5月(18)
- 2022年4月(29)
- 2022年3月(5)
- 2022年2月(6)
- 2022年1月(8)
- 2021年12月(5)
- 2021年11月(3)
- 2021年10月(4)
- 2021年9月(9)
- 2021年8月(14)
- 2021年7月(8)
- 2021年6月(5)
- 2021年5月(2)
- 2021年4月(3)
- 2021年3月(7)
- 2021年2月(2)
- 2021年1月(8)
- 2020年12月(7)
- 2020年11月(2)
- 2020年10月(6)
- 2020年9月(9)
- 2020年8月(10)
- 2020年7月(9)
- 2020年6月(18)
- 2020年5月(4)
- 2020年4月(25)
- 2020年3月(38)
- 2020年1月(21)
- 2019年12月(13)
- 2019年11月(29)
- 2019年10月(44)
- 2019年9月(17)
- 2019年8月(18)
- 2019年7月(25)
- 2019年6月(25)
- 2019年5月(17)
- 2019年4月(10)
- 2019年3月(36)
- 2019年2月(35)
- 2019年1月(28)
- 2018年12月(30)
- 2018年11月(22)
- 2018年10月(4)
- 2018年9月(7)
- 2018年8月(13)
- 2018年7月(13)
- 2018年6月(6)
- 2018年5月(5)
- 2018年4月(13)
- 2018年3月(5)
- 2018年2月(3)
- 2018年1月(8)
- 2017年12月(35)
- 2017年11月(17)
- 2017年10月(16)
- 2017年9月(17)
- 2017年8月(20)
- 2017年7月(34)
- 2017年6月(17)
- 2017年5月(15)
- 2017年4月(32)
- 2017年3月(8)
- 2017年2月(2)
- 2017年1月(5)
- 2016年12月(14)
- 2016年11月(26)
- 2016年10月(12)
- 2016年9月(25)
- 2016年8月(32)
- 2016年7月(14)
- 2016年6月(21)
- 2016年5月(17)
- 2016年4月(13)
- 2016年3月(8)
- 2016年2月(8)
- 2016年1月(18)
- 2015年12月(13)
- 2015年11月(15)
- 2015年10月(12)
- 2015年9月(18)
- 2015年8月(21)
- 2015年7月(35)
- 2015年6月(13)
- 2015年5月(9)
- 2015年4月(4)
- 2015年3月(5)
- 2015年2月(4)
- 2015年1月(13)
- 2014年12月(7)
- 2014年11月(5)
- 2014年10月(4)
- 2014年9月(8)
- 2014年8月(16)
- 2014年7月(26)
- 2014年6月(22)
- 2014年5月(28)
- 2014年4月(15)
友情链接
- Unity官网
- Unity圣典
- Unity在线手册
- Unity中文手册(圣典)
- Unity官方中文论坛
- Unity游戏蛮牛用户文档
- Unity下载存档
- Unity引擎源码下载
- Unity服务
- Unity Ads
- wiki.unity3d
- Visual Studio Code官网
- SenseAR开发文档
- MSDN
- C# 参考
- C# 编程指南
- .NET Framework类库
- .NET 文档
- .NET 开发
- WPF官方文档
- uLua
- xLua
- SharpZipLib
- Protobuf-net
- Protobuf.js
- OpenSSL
- OPEN CASCADE
- JSON
- MessagePack
- C在线工具
- 游戏蛮牛
- GreenVPN
- 聚合数据
- 热云
- 融云
- 腾讯云
- 腾讯开放平台
- 腾讯游戏服务
- 腾讯游戏开发者平台
- 腾讯课堂
- 微信开放平台
- 腾讯实时音视频
- 腾讯即时通信IM
- 微信公众平台技术文档
- 白鹭引擎官网
- 白鹭引擎开放平台
- 白鹭引擎开发文档
- FairyGUI编辑器
- PureMVC-TypeScript
- 讯飞开放平台
- 亲加通讯云
- Cygwin
- Mono开发者联盟
- Scut游戏服务器引擎
- KBEngine游戏服务器引擎
- Photon游戏服务器引擎
- 码云
- SharpSvn
- 腾讯bugly
- 4399原创平台
- 开源中国
- Firebase
- Firebase-Admob-Unity
- google-services-unity
- Firebase SDK for Unity
- Google-Firebase-SDK
- AppsFlyer SDK
- android-repository
- CQASO
- Facebook开发者平台
- gradle下载
- GradleBuildTool下载
- Android Developers
- Google中国开发者
- AndroidDevTools
- Android社区
- Android开发工具
- Google Play Games Services
- Google商店
- Google APIs for Android
- 金钱豹VPN
- TouchSense SDK
- MakeHuman
- Online RSA Key Converter
- Windows UWP应用
- Visual Studio For Unity
- Open CASCADE Technology
- 慕课网
- 阿里云服务器ECS
- 在线免费文字转语音系统
- AI Studio
- 网云穿
- 百度网盘开放平台
- 迅捷画图
- 菜鸟工具
- [CSDN] 程序员研修院
- 华为人脸识别
- 百度AR导航导览SDK
- 海康威视官网
- 海康开放平台
- 海康SDK下载
- git download
- Open CASCADE
- CascadeStudio
交流QQ群
-
Flash游戏设计: 86184192
Unity游戏设计: 171855449
游戏设计订阅号
