拓扑排序
设G=(V,E)是一个具有n个顶点的有向图,V中顶点序列v1,v2,…,vn为一个拓扑序列,当且仅当该顶点序列满足下列条件:若<vi,vj>是图中的边(即从顶点vi到顶点vj有一条路径),则在序列中顶点vi必须排在顶点vj之前。
在一个有向图中找一个拓扑序列的过程称为拓扑排序。
拓扑排序方法:
- 从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它。
- 从图中删去该顶点,并且删去从该顶点出发的全部有向边。
- 重复上述两步,直到图中不再存在没有前驱的顶点为止。
这样操作的结果有两种:1是图中全部顶点都被输出,说明图中不存在有向回路;2是图中顶点未被全部输出,剩余的顶点均有前驱顶点,说明图中存在有向回路。
AOE网与关键路径
若用前面介绍过的带权有向图(DAG)描述工程的预计进度,以顶点表示事件,有向边表示活动,边e的权c(e)表示完成活动e所需要的时间(如天数)或者活动e持续的时间。图中入度为0的顶点表示工程的开始事件(如开工仪式),出度为0的顶点表示工程的结束事件。这样的有向图称为AOE网(Activity On Edge)。
通常每个工程只有一个开始事件和一个结束事件,因此表示工程的AOE网都只有一个入度为0的顶点,称为源点(source),和一个出度为0的顶点,称为汇点(converge)。若图中存在多个入度为0的顶点,只要加一个虚拟源点,使这个虚拟源点到原来所有入度为0的点都有一条长度为0的边,将图变成只有一个源点。对存在多个汇点情况做类似处理。
利用AOE网,能够计算完成整个工程预计需要多少时间,并找出影响工程进度的“关键活动”,从而为决策者提供修改各活动的预计进度的依据。
在AOE网中,从源点到汇点的所有路径中,具有最大路径长度的路径称为关键路径。完成整个工程的最短时间就是网中关键路径的长度,也就是网中关键路径上各活动持续时间的总和,把关键路径上的活动称为关键活动。因此,只要找出AOE网中的关键活动,也就找到了关键路径。注意在一个AOE网中,可以有不止一条关键路径。
如何计算找出影响工程的关键活动:
在AOE网中,若存在两条首尾相接的边ai=<v,w>和aj=<w,z>,则称活动ai是aj的前驱活动,活动aj是ai的后继活动。一个活动可能有多个前驱活动和多个后继活动。
显然,只有活动aj的所有前驱活动都完成,事件w才发生(w是边aj的头),即活动aj才可以开始,事件w称为活动aj的触发事件。
假设事件x是源点,事件y是汇点,并规定事件x的发生时间为0。定义图中任一事件v的最早(event early)可发生事件ve(v)等于x到v的最大路径长度,即
vev=MAXp{c(p)}
式中的MAX是对x到v的所有路径p的路径长度取最大值,c(p)表示路径p的长度(路径上边长之和),即 cp=e∈p{c(e)}
于是完成整个工程所需的最少时间,等于事件y的最早可发生时间ve(y)。
开始事件x到结束事件y的最长路径就是关键路径。完成工程所需最少时间就是关键路径的长度。
为使事件v尽可能早地发生,从源点x到事件v的最长路径上的活动必须“刻不容缓”地进行,一旦触发事件发生,便立即开始,而且应当在规定时间内完成,否则事件v就不能按时发生,影响整个工程的进度。而对那些并不处在最长路径上的活动来说,即使稍稍推迟一些时间完成,也对工程的总进度无碍。
定义在不影响整个工程进度的前提下,事件v必须发生的时间称为v的最迟(event late)可发生时间,记作vl(v)。vl(v)应等于ve(y)与v到y的最长路径长度之差(y是汇点),即:vlv=vey-MAXp{c(p)}
式中的MAX对v到汇点y所有路径p的路径长度取最大值。显然,vl(y)=ve(y),vl(x)=ve(x)=0。对任何ai=<v,w>,有 ve(v)+c(ai) ≤vl(w)
如果上式取等号,即ve(v)+c(ai) ≤vl(w)(8.3)则称活动ai为关键活动。反之ai为非关键活动。
对关键活动来说,不存在富余时间。显然,关键路径上的活动都是关键活动。找出关键活动的意义在于,可以适当地增加对关键活动的投资(人力、物力等),相应减少对非关键活动的投资,从而减少关键活动的持续时间,缩短整个工程的工期。
只要计算出各顶点的ve(v)和vl(v)的值,根据8.3就能找出所有的关键活动。为便于计算,引入下面两个递推式,其中x和y分别是源点和汇点。
vex=0vew=MAX所有存在<v,w>边的vvev+c<v,w> w≠x 8.4
上式中的MAX对w的所有入边<v,w>的权值取最大值。只要从源点x起,按照顶点的拓扑次序,反复运用递推式8.4,即可求出各顶点w的ve(w)值。
vly=0vlv=MIN所有存在<v,w>边的wvlw-c<v,w> v≠y 8.5
上式中MIN对v的所有出边<v,w>的权值取最小值。只要从汇点y起,按照顶点的拓扑序列的逆序,反复运用上述递推式8.5,即可求出各顶点v的最迟可发生时间vl(v)。然后用8.3判定各有关活动是否是关键活动。
求AOE网的关键活动步骤:
- 对于源点x,置ve(x)=0;
- 对AOE网进行拓扑排序,如发现回路,工程无法进行,则退出,否则继续下一步;
- 按顶点的拓扑次序,反复用式8.4,依次求其余各顶点v的ve(v)值;(实际上步骤2和步骤3可以合在一起完成,即一边对顶点进行拓扑排序,一边求出各点的ve(v)值。)
- 对于汇点y,置vl(y)=ve(y);
- 按顶点拓扑次序之逆序,反复用式8.5,依次求其余各顶点v的vl(v)的值,即对v的所有出边<v,w>,检查是否满足式8.3,若是,则输出该边的有关信息,指明该边所对应的活动是关键活动;
- 活动ai的最早开始时间e(ai)是该活动的起点所表示事件的最早发生时间,如果由边<j,k>表示活动ai,则有e(ai)=ve(j);
- 活动ai的最迟开始时间l(ai)是该活动的终点所表示事件的最迟发生时间与该活动的所需时间之差,如果用边<j,k>表示活动ai,则有l(ai)=vl(k)-ai所需时间;
- 一个活动ai的最迟开始时间l(ai)和其最早开始时间e(ai)的差额d(ai)=l(ai)-e(ai)是该活动完成的时间余量,它是在不增加完成整个工程所需总时间的情况下,活动ai可以拖延的时间;
- 当一活动的时间余量为零时,说明该活动必须如期完成,否则就会拖延整个工程的进度,所以称l(ai)-e(ai)=0,即l(ai)=e(ai)的活动ai是关键活动。