【图论】有向无环图及其应用

本文为图论的学习总结,讲解有向无环图及其应用。

拓扑排序

由某个集合上的一个偏序得到该集合上的一个全序,这个操作称为拓扑排序。偏序指集合中仅有部分成员之间可比较,全序指集合中全体成员可比较。

AOV(Activity On Vertex)-网:用顶点表示活动,用弧表示活动间的优先关系的有向图。AOV-网中不能存在自环,检查自环的方法是:对有向图构造顶点的拓扑有序序列,若所有顶点都在序列中,则必定无自环。下图为一个 AOV-网,编程实现见【检查有向图自环】。

在这里插入图片描述

拓扑排序步骤为:

  1. 从有向图中选一个没有前驱的顶点并输出
  2. 从图中删除该顶点及其出边

重复上述两步直到所有顶点被输出,或当前图不存在无前驱的顶点为止。后一种情况说明有向图中有自环。算法复杂度为 O ( n + e ) O(n+e) O(n+e)

则上图中的拓扑有序序列为:
( C 1 , C 2 , C 3 , C 4 , C 5 , C 7 , C 9 , C 1 0 , C 1 1 , C 6 , C 1 2 , C 8 ) (C_1,C_2,C_3,C_4,C_5,C_7,C_9,C_10,C_11,C_6,C_12,C_8) (C1,C2,C3,C4,C5,C7,C9,C10,C11,C6,C12,C8)
当有向图中无环时,可利用 DFS 进行拓扑排序,最先退出 DFS 函数的顶点即出度为 0 的顶点,是拓扑有序序列的最后一个顶点,按推出 DFS 函数的先后顺序记录顶点序列即为逆向的拓扑有序序列。

关键路径

AOE(Activity On Edge)-网与 AOV 网相对,边表示活动。AOE-网是带权的有向无环图,通常用来估计工程的完成时间。下图为一个 AOE-网,代表了一个工程图。

在这里插入图片描述

其中 v 5 v_5 v5 表示 a 4 , a 5 a_4,a_5 a4,a5 已经完成, a 7 , a 8 a_7,a_8 a7,a8 可以开始。边权为活动执行天数。工程起点 v 1 v_1 v1 称为源点,结束点 v 9 v_9 v9 称为汇点。网中有很多工程可以并行进行,完成整个工程的最短时间是从开始点到完成点最长路径的长度,称为关键路径

e ( i ) e(i) e(i) 表示活动 a i a_i ai 的最早开始时间,定义活动最迟开始时间,即不推迟整个工程完成的前提下,活动 a i a_i ai 开始的最晚时间。 l ( i ) − e ( i ) l(i)-e(i) l(i)e(i) 意味着活动 a i a_i ai 的时间余量,将 l ( i ) = e ( i ) l(i)=e(i) l(i)=e(i) 的活动称为关键活动,关键路径上的所有活动都是关键活动,因此提前完成非关键活动不会加快工程进度。

扫描二维码关注公众号,回复: 11853673 查看本文章

为了求得 e ( i ) , l ( u ) e(i),l(u) e(i),l(u),应该求得事件的最早发生时间 v e ( j ) ve(j) ve(j) 和最迟发生时间 v l ( j ) vl(j) vl(j)。将活动 a i a_i ai 由弧 < j , k > <j,k> <j,k> 表示,持续时间记为 d u t ( < j , k > ) dut(<j,k>) dut(<j,k>),则有如下关系:
e ( i ) = v e ( j ) e(i)=ve(j) e(i)=ve(j)

l ( i ) = v l ( k ) − d u t ( < j , k > ) l(i)=vl(k)-dut(<j,k>) l(i)=vl(k)dut(<j,k>)

求解 v e ( j ) , v l ( j ) ve(j),vl(j) ve(j),vl(j) 分为两步:

  1. v e ( 0 ) = 0 ve(0)=0 ve(0)=0 向后递推:
    v e ( j ) = max ⁡ { v e ( i ) + d u t ( < i , j > ) } < i , j > ∈ T , j = 1 , 2 , . . . , n − 1 ve(j)=\max{\{ve(i)+dut(<i,j>)\}} \qquad <i,j>\in T,j=1,2,...,n-1 ve(j)=max{ ve(i)+dut(<i,j>)}<i,j>T,j=1,2,...,n1
    其中 T T T 是所有以第 j j j 个顶点为头的弧的集合

  2. v l ( n − 1 ) = v e ( n − 1 ) vl(n-1)=ve(n-1) vl(n1)=ve(n1) 向前递推:
    v l ( i ) = min ⁡ { v l ( j ) − d u t ( < i , j > ) } < i , j > ∈ S , i = n − 2 , . . . , 0 vl(i)=\min\{vl(j)-dut(<i,j>)\} \qquad <i,j>\in S, i=n-2,...,0 vl(i)=min{ vl(j)dut(<i,j>)}<i,j>S,i=n2,...,0
    其中 S S S 是所有以第 i i i 个顶点为尾的弧。

上面两步需要在拓扑排序的基础上进行求解。正拓扑排序求解 v e ( i ) ve(i) ve(i),逆拓扑排序求解 v l ( i ) vl(i) vl(i),可以用栈记录逆拓扑有序序列。算法复杂度为 O ( n + e ) O(n+e) O(n+e)

关键活动的速度提高是有限的,只有在不改变网的关键路径情况下,提高关键路径的速度才有效。

有帮助的话点个赞加关注吧

猜你喜欢

转载自blog.csdn.net/weixin_44413191/article/details/108195973