数据结构学习笔记——图的应用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。


相关文章
|
2天前
栈的基本应用
栈的基本应用
10 3
|
2天前
|
算法 搜索推荐 索引
数据结构与算法 排序(下)
数据结构与算法 排序(下)
9 1
|
2天前
|
缓存 算法 搜索推荐
数据结构与算法 排序(上)
数据结构与算法 排序(上)
8 0
|
2天前
|
存储 缓存 监控
中间件应用合理使用缓存和数据结构
中间件应用合理使用缓存和数据结构
14 3
[数据结构]-玩转八大排序(二)&&冒泡排序&&快速排序
[数据结构]-玩转八大排序(二)&&冒泡排序&&快速排序
|
5天前
|
搜索推荐 算法 C++
[数据结构]-玩转八大排序(一)&&插入排序&&选择排序
[数据结构]-玩转八大排序(一)&&插入排序&&选择排序
|
5天前
|
搜索推荐 C语言
【C语言/数据结构】排序(归并排序|计数排序|排序算法复杂度)
【C语言/数据结构】排序(归并排序|计数排序|排序算法复杂度)
11 0
|
5天前
|
C语言
【C语言/数据结构】排序(快速排序及多种优化|递归及非递归版本)
【C语言/数据结构】排序(快速排序及多种优化|递归及非递归版本)
6 0
|
5天前
|
C语言
【C语言/数据结构】排序(选择排序,推排序,冒泡排序)
【C语言/数据结构】排序(选择排序,推排序,冒泡排序)
12 0
|
5天前
|
C语言
【C语言/数据结构】排序(直接插入排序|希尔排序)
【C语言/数据结构】排序(直接插入排序|希尔排序)
13 4