数据结构-图-经典算法(二)

参考资料

http://www.cnblogs.com/dolphin0520/archive/2011/04/16/2017737.html

http://blog.csdn.net/liwen_7/article/details/7298736

http://blog.csdn.net/z690933166/article/details/8579260

二、拓扑排序

1、概念

对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈E(G),则u在线性序列中出现在v之前。

   通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。

   注意:

   1)只有有向无环图才存在拓扑序列;

   2)对于一个DAG,可能存在多个拓扑序列;

   如:

   

该DAG的拓扑序列为A B C D或者A C B D

 

而此有向图是不存在拓扑序列的,因为图中存在环路

2、求拓扑排序算法

无前趋的顶点优先的拓扑排序方法  

  该方法的每一步总是输出当前无前趋(即人度为零)的顶点,其抽象算法可描述为:
        NonPreFirstTopSort(G){//优先输出无前趋的顶点
            while(G中有入度为0的顶点)do{
             从G中选择一个入度为0的顶点v且输出之;
             从G中删去v及其所有出边;
             }
            if(输出的顶点数目<|V(G)|)
                 //若此条件不成立,则表示所有顶点均已输出,排序成功。
             Error("G中存在有向环,排序失败!");
         }
注意:
     无前趋的顶点优先的拓扑排序算法在具体存储结构下,为便于考察每个顶点的入度,可保存各顶点当前的入度。为避免每次选入度为0的顶点时扫描整个存储空间,可设一个栈或队列暂存所有入度为零的顶点:
     在开始排序前,扫描对应的存储空间,将人度为零的顶点均入栈(队)。以后每次选人度为零的顶点时,只需做出栈(队)操作即可。

无后继的顶点优先拓扑排序方法  

1、思想方法
     该方法的每一步均是输出当前无后继(即出度为0)的顶点。对于一个DAG,按此方法输出的序列是逆拓扑次序。因此设置一个栈(或向量)T来保存输出的顶点序列,即可得到拓扑序列。若T是栈,则每当输出顶点时,只需做入栈操作,排序完成时将栈中顶点依次出栈即可得拓扑序列。若T是向量,则将输出的顶点从T[n-1]开始依次从后往前存放,即可保证T中存储的顶点是拓扑序列。
2、抽象算法描述
  算法的抽象描述为:
      NonSuccFirstTopSort(G){//优先输出无后继的顶点
        while(G中有出度为0的顶点)do {
         从G中选一出度为0的顶点v且输出v;
         从G中删去v及v的所有人边
         }
        if(输出的顶点数目<|V(G)|)
             Error("G中存在有向环,排序失败!");
       }
3、算法求精
     在对该算法求精时,可用逆邻接表作为G的存储结构。设置一个向量outdegree[0..n-1]或在逆邻接表的顶点表结点中增加1个出度域来保存各顶点当前的出度;设置一个栈或队列来暂存所有出度为零的顶点。除了增加一个栈或向量T来保存输出的顶点序列外,该算法完全类似于NonPreFirstTopSort。

三、AOE网的关键路径

AOE网:

如果在有向图中用顶点表示事件,用弧表示活动,用弧上的权表示活动持续时间,称该带权有向图(即有向网)为边表示活动的网(activity on edge network),简称AOE网。

在AOE网中,只有一个顶点代表的事件发生后,从该顶点出发的各个弧所代表的活动才能开始,只有以弧头关联一个顶点的各个弧所代表的活动都已结束,该顶点所代表的事件才能发生。

由于在AOE网中某些活动可以并行进行,所以完成工程的最短时间是从源点到汇点路径的最大长度(指路径上各活动持续时间之和最大,而不是路径上弧的数目最多)。把从源点到汇点路径长度最大的路径称作关键路径(critical path),关键路径上的活动称作关键活动。关键活动的长度是整个工程的最短工期,加快关键活动的完成是加快工程进度缩短工期地关键。

事件Vi的最早发生时间:从V1到Vi的最长路径长度。

活动Ei的最迟开始时间:活动Ei最迟必须开始的时间。

求AOE网关键路径算法的步骤:

(1).输入e条弧<Vj,Vk>,建立AOE网的存储结构。

(2).从源点V1出发,令ve[1]=0;按拓扑有序序列次序求其余各顶点的最早发生时间ve[k](2<=k<=n),ve[k]=max{ve[j]+dut(<Vj,Vk>)};如果得到的拓扑有序序列中顶点个数小于网中顶点的个数n,说明网中存在环路,不能求关键路径算法终止,否则执行步骤(3).

(3).从汇点Vn出发,令vl[n]=ve[n],按逆拓扑有序序列求其余各顶点的最迟发生时间vl[k](n-1>=k>=1),vl[k]=min{vl[Vj]-dut(<Vk-Vj>)}。

(4).根据各顶点的ve值和vl值,求每条弧的最早开始时间e[s]和最迟开始时间l[s];e[s]等于弧s的弧尾顶点Vk的最早发生时间ve[k],而l[s]等于弧头顶点Vk的最迟发生时间减去弧s的权值;若某条弧s满足e[s]=l[s]则为关键活动,由所有关键活动构成的网的一条或几条关键路径。

原文地址:https://www.cnblogs.com/LCCRNblog/p/5269765.html