数据结构学习笔记——图的应用2(拓扑排序、关键路径)

简介: 数据结构学习笔记——图的应用2(拓扑排序、关键路径)

一、拓扑排序


(一)DAG图和AOV网


对于一个有向图,若图中不存在回路(环),则称该图是一个DAG图;若以DAG图中的顶点表示活动,以边表示活动的先后次序,则称其是一个AOV网。

例如,这就是一个DAG图:

1667297026041.jpg



(二)拓扑排序的概念


对于一个DAG图,其所有顶点组成一个线性序列,且每个顶点只出现一次,对于图G=(V,E)中的任意一对顶点A和B,顶点A在线性序列中排在顶点B的前面,即<A,B>∈E(G),图中存在由A到B的路径,则这种序列称为拓扑序列,称为拓扑排序。

若一个有向无回路图的拓扑序列是唯一的,对其而言并不能唯一确定该图。


(三)拓扑排序的步骤


对于一个AOV网进行拓扑排序:

1、从网中找选择一个没有前驱,即入度ID(v)=0的顶点;

2、删除该顶点且删除由该顶点的所有起始边(出度的边),并将该顶点输出;

3、重复(1)和(2)步骤,直至AOV网为空或不存在没有前驱的结点为止;

4、最后得到一个序列,即拓扑排序。


AOV网的拓扑排序的序列不止一个,也可以能有多个,是由于当网中有多个入度为0的顶点时,进行拓扑排序,得到的序列不止一种。

例如,对于下面这个图,对其进行拓扑排序:

1667297039700.jpg


1、由该图可知,ID(V1)=0、ID(V6)=0,即入度为0的顶点有V1、V6。

2、以V1开始(若以V6序列开始也可以,只是得到的拓扑序列不同),删除顶点V1以及其出度并输出该顶点,得到如下:

1667297048333.jpg

3、由得到的图可知,ID(V3)=0、ID(V6)=0,即入度为0的顶点为V3和V6,以V3继续(若以V6序列也可以,只是得到的拓扑序列不同),删除顶点V3以及其出度并输出该顶点,得到如下:

1667297055414.jpg

4、由得到的图可知,ID(V6)=0,即入度为0的顶点为V6,删除顶点V6以及其出度并输出该顶点,得到如下:

1667297062018.jpg

5、由得到的图可知,ID(V5)=0,即入度为0的顶点为V5,删除顶点V5以及其出度并输出该顶点,得到如下:

1667297072210.jpg

6、由得到的图可知,ID(V4)=0,即入度为0的顶点为V4,删除顶点V4以及其出度并输出该顶点,得到如下:

1667297082660.jpg

7、加上最后的顶点V2,输出该顶点,此时图中所有顶点都输出,即得到该图的一个拓扑序列为V1、V3、V6、V5、V4、V2。


(四)拓扑排序的时间复杂度


若一个有向图的所有顶点不能排成一个拓扑序列(有向图存在回路,则一定不存在拓扑排序),由于该图中一定存在回路,即该图中存在含有顶点数目大于1的强连通分量。

对于图G=(V,E),当采用邻接矩阵存储图时拓扑排序的时间复杂度为O(|V|2);而采用邻接表存储图时,由于在输出顶点时还要删除其所有起始边(出度),所以拓扑排序的时间复杂度为O(|V|+|E|)。


二、逆拓扑排序和DFS算法的应用


(一)逆拓扑排序


若将拓扑排序的步骤中的一开始的针对入度进行排序改为针对出度,则以下是逆拓扑排序的步骤,对于一个AOV网进行逆拓扑排序:

1、从网中找选择一个没有后继,即出度OD(v)=0的顶点;

2、删除该顶点且删除由该顶点的所有终止边(入度的边),并将该顶点输出;

3、重复(1)和(2)步骤,直至AOV网为空或不存在没有后继的结点为止;

4、最后得到一个序列,即逆拓扑排序。


与拓扑排序一样,AOV网的逆拓扑排序的序列不止一个,也可以能有多个,是由于当网中有多个出度为0的顶点时,进行逆拓扑排序,得到的序列不止一种。

例如,对于下面这个图,对其进行拓扑排序:


1667297101657.jpg

1、由该图可知,OD(V3)=0、OD(V5)=0,即出度为0的顶点有V3、V5。

2、以V3开始(若以V5序列开始也可以,只是得到的逆拓扑序列不同),删除顶点V3以及其入度并输出该顶点,得到如下:

1667297109889.jpg

3、由得到的图可知,OD(V5)=0,即出度为0的顶点为V5,以V5继续,删除顶点V5以及其入度并输出该顶点,得到如下:

1667297116290.jpg

4、由得到的图可知,OD(V4)=0,即出度为0的顶点为V4,以V4继续,删除顶点V4以及其入度并输出该顶点,得到如下:

1667297125000.jpg

5、由得到的图可知,OD(V2)=0,即出度为0的顶点为V2,以V2继续,删除顶点V2以及其入度并输出该顶点,得到如下:

1667297132564.jpg

6、加上最后的顶点V1,输出该顶点,此时图中所有顶点都输出,即得到该图的一个逆拓扑序列为V3、V5、V4、V2、V1。


(二)DFS算法的应用


对于一个AOV网也可以采用DFS算法,由于当从有向无环图中某一顶点开始深度优先搜索时,最先得到的顶点即为出度等于0的顶点,所以通过DFS算法得到的顶点序列刚好为逆向的拓扑序列。(DFS算法的知识点可以看之前的文章:图的遍历算法(深度优先搜索和广度优先搜索))


三、关键路径


(一)AOE网


对于AOV网,它是以顶点来表示活动、边上无权值,只表示活动的先后次序;而对于AOE网,是以边来表示活动,且边上有权值,表示完成该活动的开销(时间),其对比如下表:

1667297167301.jpg


(二)源点和汇点


在一个表示工程的AOE网中,只存在一个入度等于0,即ID(v)=0的顶点,称为源点,代表整个工程的开始;同样,也只存在一个出度等于0,即OD(v)=0的顶点,称为汇点,代表整个工程的结束。


(三)关键路径的概念


在AOE网中,由源点到汇点的有向路径可能有多条,从而完成活动的路径长度也不同,将所有路径中具有最大路径长度的路径称为关键路径,且这条路径上的所有活动称为关键活动,是决定整个工程的关键因素,关键路径是整个工程所完成的最短时间。

一个AOE网的关键路径不唯一,若延长关键路径上的关键活动的时间,则整个工程的时间也会随着延长;另外,只有缩短所有的关键路径上共有的任意一个关键活动的持续时间,才会缩短关键路径长度。


(四)关键路径的算法步骤


1、根据所给的图,求得该图的拓扑有序序列和逆拓扑有序序列;

2、通过得到的序列,求得每个事件的最早发生时间和最迟发生时间:

3、根据(2)得到的结果,求得每个活动的最早发生时间和最迟发生时间。

4、根据(3)得到的结果,找到最早发生时间和最迟发生时间相同的活动,就得到了关键活动,由关键活动连成的路径即为关键路径。


例如,下面是一个AOE网,求其关键路径。


1667297189250.jpg

1、首先求其拓扑序列和逆拓扑序列:

拓扑序列和逆拓扑序列分别为V3、V1、V4、V2、V6、V5和V5、V6、V2、V4、V1、V3。

2、设ve(V)为顶点V代表的事件的最早发生时间,依照拓扑序列的先后顺序求各顶点所对应事件的最早发生时间:

设事件0的开始时间为0,即ve(V3)=0,可得:

ve(V1)=ve(V3)+3=0+3=3;

ve(V4)=ve(V3)+3=0+3=3;

由于到V2的路径有两条,分别是V1→V2和V4→V2,要取其中权值最大者,也就是最早发生时间,ve(V2)=max{ve(V1)+2,ve(V4)+6}=max{3+2,3+6}=9;

ve(V6)=ve(V4)+1=3+1=4;

由于到V5的路径有两条,分别是V2→V5和V6→V5,要取其中权值最大者,也就是最早发生时间,ve(V5)=max{ve(V2)+5,ve(V6)+2}=max{9+5,4+2}=14。

3、设vl(V)为顶点V代表的事件的最迟发生时间,最迟发生时间是在不推迟整个工程完成的前提下,该事件最迟必须发生的时间,依照逆拓扑序列的先后顺序求各顶点所对应事件的最迟发生时间,且由事件的最早发生时间,可得:

vl(V5)=ve(V5)=14;

vl(V6)=vl(V5)-2=14-2=12;

vl(V2)=vl(V5)-5=14-5=9;

由于回V4的路径有两条,分别是V3→V1和V3→V4,要取其中权值最小者,也就是最迟发生时间,vl(V4)=min{vl(V2)-6,vl(V6)-1}=min{9-6,12-1}=3;

vl(V1)=vl(V2)-2=9-2=7;

由于回V3的路径有两条,分别是V4→V2和V4→V6,要取其中权值最小者,也就是最迟发生时间,vl(V3)=min{vl(V1)-3,vl(V4)-3}=min{7-3,3-3}=0。

4、求每个活动的最早发生时间和最迟发生时间,设e(ak)和l(ak)为当前活动ak的最早发生时间和最迟发生时间,由于事件代表一个新活动的开始或旧活动的结束,所以事件的最早发生时间就是由这个事件所发出的活动的最早发生时间,即ve(V);而活动的最迟发生时间是事件的最迟发生时间减去以它为结束点的活动的持续时间:

1667297199157.jpg

(1)活动的最早发生时间:

e(a0)=e(a1)=ve(V3)=0;

e(a2)=e(a3)=ve(V4)=3;

e(a4)=ve(V1)=3;

e(a5)=ve(V2)=9;

e(a6)=ve(V6)=4。

(2)活动的最迟发生时间:

l(a0)=vl(V1)-3=7-3=4;

l(a1)=vl(v4)-3=3-3=0;

l(a2)=vl(V2)-6=9-6=3;

l(a3)=vl(V6)-1=12-1=11;

l(a4)=vl(V2)-2=9-2=7;

l(a5)=vl(V5)-5=14-5=9;

l(a6)=vl(V5)-2=14-2=12;

由以上得到的活动的最早/最迟发生时间,整理得关键活动,即最早最早发生时间和最迟发生时间相同的活动,如下:

活动 最早发生时间 最迟发生时间 关键活动
a0 0 4
a1 0 0
a2 3 3
a3 3 11
a4 3 7
a5 9 9
a6 4 12



5、由关键活动所连成的路径即为所求的关键路径,可知关键路径为:

V3→V4→V2→V5,

关键路径所持续的时间为整个工程所持续的时间(整个图中所有活动完成的时间):

a1+a2+a5=0+3+9=12。


例、下图所示的AOE网表示一项包含8个活动的工程,求活动d的最早开始时间和最迟开始时间。

1667297218122.jpg


解:活动d的最早开始时间为事件2的最早发生时间,即max{a,b+c}=max{3,12}=12;求出图的关键路径长度,先求得拓扑排序为1、3、2、4、5、6:

设ve(1)=0,

ve(2)=ve(1)+3=3;

ve(3)=ve(1)+8=8;

ve(4)=ve(2)+7=10;

ve(5)=max{ve(2)+6,ve(3)+10}=max{9,18}=18;

ve(6)=max{ve(4)+6,ve(5)+9}=max{16,27}=27;

所以关键路径长度为27。

由于活动d的最迟开始时间为该活动弧的终点所表示的事件的最迟发生时间与该活动所需时间之差,即min{27-g}=min{21},

所以活动的最迟开始时间为21-d=21-7=14。


相关文章
|
27天前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
42 1
|
1月前
|
存储 算法 C语言
通义灵码在考研C语言和数据结构中的应用实践 1-5
通义灵码在考研C语言和数据结构中的应用实践,体验通义灵码的强大思路。《趣学C语言和数据结构100例》精选了五个经典问题及其解决方案,包括求最大公约数和最小公倍数、统计字符类型、求特殊数列和、计算阶乘和双阶乘、以及求斐波那契数列的前20项和。通过这些实例,帮助读者掌握C语言的基本语法和常用算法,提升编程能力。
63 4
|
26天前
|
机器学习/深度学习 存储 人工智能
数据结构在实际开发中的广泛应用
【10月更文挑战第20天】数据结构是软件开发的基础,它们贯穿于各种应用场景中,为解决实际问题提供了有力的支持。不同的数据结构具有不同的特点和优势,开发者需要根据具体需求选择合适的数据结构,以实现高效、可靠的程序设计。
60 7
|
1月前
|
算法 搜索推荐 Java
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
24 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
|
1月前
|
存储 搜索推荐 算法
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
23 1
|
1月前
探索数据结构:队列的的实现与应用
探索数据结构:队列的的实现与应用
|
1月前
|
存储
探索数据结构:单链表的实践和应用
探索数据结构:单链表的实践和应用
|
1月前
|
存储 测试技术
探索数据结构:顺序表的实现与应用
探索数据结构:顺序表的实现与应用
|
18天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
94 9