第七章、图
7.5有向无环图及其应用
顾名思义,有向无环图就是不带环的有向图,简称DAG图
应用:判断工程能否顺利进行,求出最短完成时间
7.5.1拓扑排序
AOV网:顶点表示活动,弧表示活动间的优先关系
AOV网中不应该出现环,这样就能够找到一个顶点序列,使得每个顶点代表的活动的前驱活动都排在该顶点的前面,这样的序列称为拓扑序列,由AOV网构造拓扑序列的过程称为拓扑排序
检测AOV网中是否带环:构造拓扑序列,看是否包含所有顶点
构造拓扑序列步骤:
- 选一个没有前驱的顶点输出
- 图中删去该顶点,以及所有从该顶点出发的弧
- 重复上面两步,直到所有顶点都输出或没有不带前驱的顶点
算法
思路:使用邻接表存储,为了方便找没有前驱的结点,每个顶点加上它的入度信息。删去从该顶点出发的弧,就相当于把该顶点邻接的顶点的入度都减一。同时为了避免删去同一个顶点,设立辅助栈专门存放没有前驱的顶点
描述:
- 查找邻接表中入度为0的顶点,入栈
- 栈非空,进行拓扑排序
- 栈顶顶点出栈并输出
- 查找出栈顶点的所有后继顶点,将其入度减一,并把此时入度为0的点入栈
- 栈空时,输出全部顶点则拓扑排序完成,否则说明有环
Status
找入度为0的顶点需要
7.5.2关键路径
利用拓扑排序可以判断工程能否顺利进行,下面来研究工程完成的最短时间。
AOE网:用边来表示活动,顶点表示活动的完成状态,是带权的有向无环图,权表示活动持续的时间
可解决问题:
- 工程能否进行(不管AOE还是AOV都可以)
- 工程最短完成时间(从初始顶点到最终顶点的最长路径)
- 哪些活动是关键(不可推迟的活动)
几个概念:
- 关键路径:从初始顶点到最终顶点的最长路径
- 顶点
的最早开始时间:初始点到该顶点的最长路径长度,记为,它决定了以该顶点开始的活动的最早发生时间,所以
- 顶点
的最迟开始时间:在不推迟整个工期的前提下,工程达到顶点所表示的状态最晚能容忍的时间,记为,它决定了所有以该状态结束的活动的最迟发生时间,所以
- 关键活动:关键路径上的活动,最早开始时间和最迟开始时间相等
最早和最迟开始时间的递推关系
按拓扑顺序求,最早--从前往后,前驱顶点的最早开始时间与边的权重之和最大者,最迟--从后往前,后继顶点的最迟开始时间与边的权重之差的最小者。
算法描述--拓扑有序和逆拓扑有序
- 输入弧,构建AOE网
- 初始点满足
,按照递推关系求出其余顶点的最早开始时间
- 如果拓扑排序顶点数目不足,说明有环,终止,否则继续
- 令终止点的最迟开始时间等于最早开始时间
,根据逆向递推关系得到其余顶点的最迟开始时间
- 由顶点的最早最迟开始时间得到边的最早最迟开始时间
,如果两者相等则为关键活动
最早开始时间:
最迟开始时间:
- 边的最早开始时间(往前看),为前面顶点的最早开始时间;
- 边的最迟开始时间(往后看),为后面顶点的最迟开始时间减去边的权重
关键活动为
关键路径为
问:
答:不能,当有关键路径多条,只有缩短它们的公共边才能缩短工期。
7.6最短路径问题
最短路径:两个顶点之间满足弧上权值之和最小的那条路径
两类问题:一个源点到其余顶点的最短路径;每对顶点的最短路径
迪杰斯特拉算法
思想:按照最短路径长度递增的次序,依次求出从源点到其余顶点的最短路径和长度。每次求出到一个顶点的最短路径,都要以该顶点作为中间点,对其余顶点的最短路径进行修改。每次都能确定一个顶点的最短路径,所以
算法准备:
- 设立集合S记录已经求得最短路径的顶点,初始状态只有源点。
- 设立数组D,D[j]表示从源点到j点当前的最短路径长度(初始时如果源点到j有弧则为弧的权,否则设为无穷大)
- 设立指针数组path,path[j]指向一个链表的基地址,保存长度为D[j]的路径对应的顶点序列,初始值为空
算法描述:
(1)初始化
-
--S开始只有一个点
-
--D的每个元素为弧的权
-
--如果有弧,则有该路径
(2)求出最短路径长度--选D中最小的对应的顶点加入S中
(3)修改--比较从中间顶点k到i短,还是原来的路径短
如果修改了,那么还要更改路径为
(4)判断
如果