拓撲排序和關鍵路徑


1. 拓撲排序

  不存在有向環路的有向圖稱為無環路有向圖。無環有向圖可用於表示偏序集。設R是有窮集合X上的偏序關系,對X的每個v,用一個以v為標號的頂點表示,由此構成頂點集V。對R中任意一個序對(a,b),a不等於b,由對應的兩個頂點建立一條邊(a,b),由此構成邊集E,則G=(V,E)是無環路有向圖。

  下面介紹由廣度優先搜索算法演變而得到的拓撲排序算法。

  給定一個無環路有向圖G=(V,E),各頂點的編號為V={1,2,...,n}。要求用label[i]對每個頂點i重新進行編號,使得若i是j的前導頂點(廣度優先搜索),則label[i] < label[j]。即拓撲排序是將無環路有向圖的每個頂點排成一個線性序列,使得當從頂點i到頂點j存在一條邊時,則在線性序列中,將i排在j的前面。

代碼如下:

    //輸入為鄰接表
    void TopoOrder(GRAPH L)
    {
        QUEUE Q;
        vertex v,w;
        int nodecount;
        MakeNull(Q);
        //入度為0的頂點進隊
        for(v=1;v<=n;v++)
            if(indegree[v]=0)
                EnQueue(v,Q);
            nodecount = 0;
        while(!Empty(Q)) {
            v = Front(Q);
            DeQueue(Q);
            count << v;
            nodecount ++;
            for(鄰接於v的每個頂點w) {
                indegree[w] = indegree[w] - 1;//刪除由v發出的邊
                if(indegree[w] == 0)
                    EnQueue(w,Q);
            }
        }
        if(nodecount < n)
            cout << "you huan lu a!";
    }

2. 關鍵路徑

2.1 概念

  在引進“關鍵路徑”這個詞之前,先介紹一下與它密不可分的幾個概念。如果在帶權的有向圖中,用頂點表示事件,邊表示活動,權表示活動持續的時間。把這樣的有向圖稱為關於邊的活動網。與之相對應,若用頂點表示活動,用邊表示活動的先后順序關系,這樣的有向圖稱為關於頂點的活動網,例如拓撲圖。將這些活動網統稱為AOE網

image_1be7ohfpdum21jihd81h9gbt39.png-22.3kB

  事件v5表示活動a4和a5已結結束,a7和a8可以開始。邊上的數字為持續的時間。

  顯然,在AOE網中,由於有些活動可以同時進行,所以完成工程最小時間是從起始點到結束點最長路徑的長度,把從起始點到結束點具有最大長度的路徑稱為關鍵路徑。圖中的a1-a4-a7-a10(長為18)就是其中一條關鍵路徑。關鍵路徑的長度代表完成這個工程最少需要的時間。這里需要注意,活動的時間只是指完成該活動的最少時間,實際上可能會拖延什么的。

  從AOE網的起始點v1到其中某一頂點vi的最長路徑的長度,稱為事件vi的最早發生時間,記為VE[i]。如事件v5的最早發生時間為7。

  用E(i)表示活動ai的最早開始時間。事件vi的最早發生時間決定了以vi為起點的所有邊上的活動的最早開始時間。如E(7)=E(8)=事件v5的最早發生時間=7。

  對於活動ai,還定義一個最遲開始時間,它是不使整個工程的完成時間拖延的最晚開始時間。用L(i)表示。如,L(6)=18-a11-a9-a6=8。

  對於事件vi,也有一個最遲發生時間VL[i]。

關鍵路徑上,所有活動都滿足E(i) = L(i),把滿足這一等式的所有活動稱為關鍵活動

  活動ai的最遲開始時間和最早開始時間之差表示ai的完成時間余量,即允許ai延緩的時間。

2.2 尋找關鍵活動

  求解關鍵活動在於求解E(i)和L(i)。

  設活動ai所對應的邊為(k,m),並且用ACT[k][m]來表示一個活動的持續時間,很明顯:
    E(i) = VE[k] 或者用E(k,m)
    L(i) = VL[m] - ACT[k][m] 或者用L(k,m)

現在就轉化為求解VE[i]和VL[i],分成兩步:

  • 前進階段:從VE1=0開始,沿着路徑上每條邊的方向,應用如下公式求出每個事件的最早發生時間:
        VE[m] = max{VE[k]+ACT[k][m]},k是m的直接前導頂點
  • 回退階段:從已求出的VL[n]=VE[n]開始,沿着路徑上每條邊的相反方向,應用如下公式:
        VL[k] = min{VL[m]-ACT[k][m]},m為k的直接后續頂點

可以用類似拓撲排序的算法求出L[i]和E[i],對於這兩者都相等的活動則是關鍵活動,將所有非關鍵活動刪除后得到的圖,任意一條路徑都是關鍵路徑。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM