【AOE 网】
日常生活中,一项大的工程可以看作是由若干个子工程组成的集合,这些子工程之间必定存在一定的先后顺序,即某些子工程必须在其他的一些子工程完成后才能开始
用结点表示活动,用弧表示活动间优先关系,形成的无权 DAG 图,被称为顶点活动网络
而用结点表示事件,用弧表示活动,用边权表示活动持续时间的有权 DAG 图,被称为边活动网络(Activity On Edge Network,AOE 网)
与 AOV 网相同,AOE 网同样存在如下基本概念:
- 活动:子工程组成的集合,每个子工程即为一个活动
- 前驱活动:有向边起点的活动称为终点的前驱活动,只有当一个活动的前驱全部都完成后,这个活动才能进行
- 后继活动:有向边终点的活动称为起点的后继活动
- 源点:工程开始的结点,入度为 $0$
- 汇点:工程结束的结点,出度为 $0$
【关键路径】
AOE 网,主要用于工程管理,在 AOE 网中,有些活动是可以并行进行的,这就导致从源点到汇点的有向路径有多条,且这些路径长度不同
完成不同路径上的活动所需时间不同,只有所有路径上的活动都已完成,整个工程才算结束
关键路径被定义为从源点到汇点的具最大路径长度的路径,该路径上的活动被称为关键活动
关键活动决定了整个工程的工期,因此可以通过加快关键活动来缩短工程的工期,但不能任意缩短关键活动,当缩短到一定程度,会使得关键活动变为非关键活动
而 AOE 网中的关键活动不唯一,对于有几条关键路径的网,只提高一条关键路径上的关键活动并不能缩短整个工程的工期,只有加快包括在所有关键路径上的关键活动,才能缩短工期
此外,完成整个工程的最短时间就是关键路径的长度,即关键路径上各活动花费开销总和,这是因为关键活动若不按期完成,则整个工程的完成时间就会被延长
因此,只要找到关键路径,就能得到工程的最短完成时间
【关键路径寻找参量】
事件 $v_k$ 的最早发生时间 $ve(k)$
$ve(k)$ 是从源点 $v_1$ 开始到结点 $v_k$ 的最大路径长度,其是在保证工程顺利完成的基础上,事件最早的开始时间,其决定了所有从 $v_k$ 开始的活动能够开工的最早时间,因此称为最早发生时间
求解 $ve(k)$ 可以从源点 $ve(1)=0$ 开始
按照拓扑排序的规则,每输出一个入度为 $0$ 的顶点 $v_j$,计算它所有直接后继顶点 $v_k$ 的最早发生时间,即有:
事件 $v_k$ 的最晚发生时间 $vl(k)$
$vl(k)$ 是在保证工程顺利完成的基础上,事件 $v_k$ 最迟的开始时间,因此被称为最晚发生时间
求解 $vl(k)$ 可以从汇点 $vl(n)=ve(n)$ 开始
按照逆拓扑排序的规则,每输出一个出度为 $0$ 的顶点 $v_j$,计算它所有直接前驱顶点 $v_k$ 的最晚发生时间,即有:
活动 $a_i$ 的最早开始时间 $ee(i)$
$ee(i)$ 是在保证工程顺利完成的基础上,活动 $a_i$ 最早的必须开始时间,因此被称为最早开始时间
根据 AOE 网的性质,只有事件 $v_k$ 发生后,活动 $a_i$ 才能开始,那么若活动 $a_i$ 由 $< v_k, v_j >$ 表示,活动 $a_i$ 的最早开始时间等于事件 $v_k$ 的最早发生时间,即:
活动 $a_i$ 的最晚开始时间 $el(i)$
$el(i)$ 是在保证工程顺利完成的基础上,活动 $a_i$ 最迟的必须开始时间,因此被称为最晚开始时间
若活动 $a_i$ 由弧 $< v_k, v_j >$ 表示,则 $a_i$ 的最晚开始时间要保证事件 $v_j$ 的最迟发生时间不拖后,即:
活动 $a_i$ 的松弛时间 $d(i)$
$d(i)$ 是指活动完成的时间余量,即在不增加完成整个工程所需时间的情况下,活动 $a_i$ 可以拖延的时间,其值为 $a_i$ 的最晚开始时间 $el(i)$ 与最早开始时间 $ee(i)$ 的差值,即:
若一个活动松弛时间为 $0$,那么说明该活动必须按期完成,否则会影响整个工程的进度
也就是说,若满足 $el(i)-ee(i)=0$,即满足 $el(i)=ee(i)$ 时,活动 $a_i$ 是关键活动
【关键路径的求解】
关键路径的求解算法如下:
1)求结点的最早发生时间 $ve(i)$
从源点出发,令 $ve(1)=0$,按拓扑序列,求解每个顶点 $i$ 的最早发生时间 $ve(i)$,即:
2)求结点的最晚发生时间 $vl(i)$
从汇点出发,令 $vl(n)=ve(n)$,按逆拓扑序列,求解每个顶点 $i$ 的最晚发生时间 $vl(i)$,即:
3)求弧的最早开始时间 $ee(i)$
根据各顶点 $i$ 的最早发生时间 $ve(i)$ 求所有弧 $< v_k, v_j >$ 的最早开始时间 $ee(i)$,即:
4)求弧的最晚开始时间 $el(i)$
根据各顶点 $i$ 的最晚发生时间 $vl(i)$ 求所有弧 $< v_k, v_j >$ 的最晚开始时间 $el(i)$,即:
4)求弧的松弛时间 $d(i)$
计算所有弧的松弛时间 $d(i)$,找出所有 $d(i)=0$ 的弧,其构成一条关键路径,即:
【实例】
在上图所示的 AOE 网中,从源点事件 $1$ 和汇点事件 $6$,进行拓扑排序,可以得到一个拓扑序列为 $132456$,由此,事件最早发生时间 $ve(i)$ 与事件最晚发生时间 $vl(i)$ 如下表:
事件 $i$ | $1$ | $3$ | $2$ | $4$ | $5$ | $6$ |
---|---|---|---|---|---|---|
$ve(i)$ | $0$ | $8$ | $12$ | $19$ | $18$ | $27$ |
$vl(i)$ | $0$ | $8$ | $12$ | $21$ | $18$ | $27$ |
进一步,由于活动 $i$ 是由弧 $< v_k, v_j >$ 表示,那么,活动 $a$ 到活动 $h$ 的最早开始时间 $ee(i)$ 与最晚开始时间 $el(i)$ 如下表:
活动 $i$ | $a$ | $b$ | $c$ | $d$ | $e$ | $f$ | $g$ | $h$ |
---|---|---|---|---|---|---|---|---|
对应弧 $< v_k, v_j >$ | $< 1,2 >$ | $< 3,2 >$ | $< 1,3 >$ | $< 2,4 >$ | $< 2,5 >$ | $< 3,5 >$ | $< 4,6 >$ | $< 5,6 >$ |
$ve(v_k)$ | $0$ | $8$ | $0$ | $12$ | $12$ | $8$ | $19$ | $18$ |
$vl(v_j)$ | $12$ | $12$ | $8$ | $19$ | $18$ | $18$ | $27$ | $27$ |
弧长 | $3$ | $4$ | $8$ | $7$ | $6$ | $10$ | $6$ | $9$ |
$ee(i)$ | $0$ | $8$ | $0$ | $12$ | $12$ | $8$ | $19$ | $18$ |
$el(i)$ | $12-3=9$ | $12-4=8$ | $8-8=0$ | $21-7=14$ | $18-6=12$ | $18-10=8$ | $27-6=21$ | $27-9=18$ |
故活动的松弛时间 $d(i)$ 如下表:
活动 $i$ | $a$ | $b$ | $c$ | $d$ | $e$ | $f$ | $g$ | $h$ |
---|---|---|---|---|---|---|---|---|
$ee(i)$ | $0$ | $8$ | $0$ | $12$ | $12$ | $8$ | $19$ | $18$ |
$el(i)$ | $9$ | $8$ | $0$ | $14$ | $12$ | $8$ | $21$ | $18$ |
$d(i)$ | $9$ | $0$ | $0$ | $2$ | $0$ | $0$ | $2$ | $0$ |
可知,活动 $b$、$c$、$e$、$f$、$h$ 为关键活动,他们构成的路径 $cbeh$、$cbfh$ 为两条关键路径
在这两条关键路径中,活动 $c$、$b$、$h$ 在所有的关键路径中,因此,加快这三个活动的进度,能够缩短工期
【实现】
输出关键路径
根据关键路径的定义,依次求出 $ve$、$vl$、$ee$、$el$,然后比较 $ee$、$el$ 进行输出
1 | int n,m; |
求关键路径长度
由于关键路径是具有最大路径长度的路径,因此直接求有向图的最长路即为关键路径的长度
1 | struct Node { |