拓撲排序
乙個無環的有向圖稱為無環圖(directed acyclic graph),簡稱dag圖。 所有的工程或者某種流程都可以分為若干個小的工程或者階段,稱這些小的工程或階段為「活動」。
這些子程式之間存在一定的約束,其中某種子工程的開始必須在另一些子工程完成之後。因此dag圖表示乙個工程,其中有向邊表示約束關係。這種有向圖必須是無環的。如果出現了環(有向環),那麼向前遞推,環路上的任一子工程開始的先決條件必然是自己,顯然矛盾的。如果設計出這樣的工程圖,工程無法進行。拓撲排序就是測試乙個工程能否順利進行。
【例】計算機專業的學生必須完成一系列規定的專業基礎課和專業課才能畢業,這個過程就可以被看成是乙個大的工程,而活動就是學習每一門課程。我們不妨把這些課程的名稱與相應的代號列於表 7.2 。
表 7.2 計算機專業的學生必須完成課程的名稱與相應代號
課程代號 課程名 先行課程名 課程代號 課程名 先行課程名
c 1 程式設計導論 無 c 9 演算法分析 c 3
c 2 數值分析 c 1 , c 14 c 10 高階語言 c 3 , c 4
c 3 資料結構 c 1 , c 14 c 11 編譯系統 c 10
c 4 組合語言 c 1 , c 13 c 12 作業系統 c 11
c 5 自動機理論 c 15 c 13 解析幾何 無
c 6 人工智慧 c 3 c 14 微積分 c 13
c 7 計算機圖形學 c 3 ,c 4 ,c 10 c 15 線性代數 c 14
c 8 計算機原理 c 4
若以圖中的頂點來表示活動,有向邊表示活動之間的優先關係,則這樣的有向圖稱為 aov(activity on vertex network) 網。在 aov 網中,若從頂點 v i 到頂點 v j 之間存在一條有向路徑,稱頂點 v i 是頂點 v j 的前趨,或者稱頂點 v j 是頂點 v i 的後繼。若 是圖中的弧,則稱頂點 v i 是頂點 v j 的直接前趨,頂點 v j 是頂點 v i 的直接後繼。
這種優先關係可以用圖 7.18 所示的有向圖來表示。其中,頂點表示課程,有向邊表示前提條件,若課程 v i 為課程 v j 的前行課,則必然存在有向邊 &v i ,v j > 。
對 aov 網進行拓撲排序的方法和步驟如下:
1. 從 aov 網中選擇乙個沒有前趨的頂點(該頂點的入度為 0 )並且輸出它;
2. 從網中刪去該頂點,並且刪去從該頂點發出的全部有向邊;
3. 重複上述兩步,直到剩餘網中不再存在沒有前趨的頂點為止。
操作的結果有兩種:
一種是網中全部頂點都被輸出,這說明網中不存在有向迴路,拓撲排序成功;
另一種是網中頂點未被全部輸出,剩餘的頂點均有前趨頂點,這說明網中存在有向迴路,不存在拓撲有序序列。
【例】圖 7.19 給出了乙個 aov 網實施上述步驟的例子。
這樣得到乙個拓樸序列 v 1 , v 6 , v 4 , v 3 , v 2 , v 5 。
為了避免在每一步選入度為零的頂點時重複掃瞄表頭陣列,利用表頭陣列中入度為零的頂點域作為鏈棧域,存放下乙個入度為零的頂點序號,零表示棧底,棧頂指標為 top ,寄生在表頭陣列的入度域中的入度為零的頂點鍊錶如圖 7.20(b) 所示。
拓樸排序演算法梗概如下:
1. 掃瞄頂點表,將入度為零的頂點入棧;
2.while ( 棧非空 )
演算法的時間複雜度
對乙個具有 n 個頂點, e 條邊的網來說,初始建立入度為零的頂點棧,要檢查所有頂點一次,執行時間為 o(n) ;排序中,若 aov 網無迴路,則每個頂點入、出棧各一次,每個表結點被檢查一次,因而執行時間是 o(n+e) 。所以,整個演算法的時間複雜度是 o(n+e) 。
關鍵路徑
若在帶權的有向圖中,以頂點表示事件,以有向邊表示活動,邊上的權值表示活動的開銷(如該活動持續時間),則此帶權的有向圖稱為邊表示活動的網 (activity on edge network) ,簡稱 aoe 網。
【例】圖 7.21 是乙個網。其中有 9 個事件 v 1 , v 2 , … , v 9 ; 11 項活動 a 1 , a 2 , … , a 11 。每個事件表示在它之前的活動已經完成,在它之後的活動可以開始。如 v 1 表示整個工程開始, v 9 表示整個工程結束。 v 5 表示活動 a 4 和 a 5 已經完成,活動 a 7 和 a 8 可以開始。與每個活動相聯絡的權表示完成該活動所需的時間。如活動 a 1 需要 6 天時間可以完成。
(1)aov 網具有的性質
⒈ 只有在某頂點所代表的事件發生後,從該頂點出發的各有向邊所代表的活動才能開始。
⒉ 只有在進入某一頂點的各有向邊所代表的活動都已經結束,該頂點所代表的事件才能發生。
⒊ 表示實際工程計畫的 aoe 網應該是無環的,並且存在唯一的入度過為 0 的開始頂點和唯一的出度為 0 的完成頂點。
(2)由事件 v j 的最早發生時間和最晚發生時間的定義 , 可以採取如下步驟求得關鍵活動 :
1. 從開始頂點 v 1 出發 , 令 ve(1)=0, 按拓樸有序序列求其餘各頂點的可能最早發生時間。
ve(k)=max ( 7.1 )
j ∈ t
其中 t 是以頂點 v k 為尾的所有弧的頭頂點的集合 (2 ≤ k ≤ n) 。
如果得到的拓樸有序序列中頂點的個數小於網中頂點個數 n ,則說明網中有環,不能求出關鍵路徑,演算法結束。
2. 從完成頂點 v n 出發,令 vl(n)=ve(n) ,按逆拓樸有序求其餘各頂點的允許的最晚發生時間 :
vl(j)=min
k ∈ s
其中 s 是以頂點 v j 是頭的所有弧的尾頂點集合 (1 ≤ j ≤ n-1) 。
3. 求每一項活動 a i (1 ≤ i ≤ m) 的最早開始時間 e(i)=ve(j) ;最晚開始時間
l(i)=vl(k)-dut()
。若某條弧滿足 e(i)=l(i) ,則它是關鍵活動。
對於圖 7.21 所示的 aoe 網,按以上步驟的計算結果見表 7.3 ,可得到 a 1 , a 4 , a 7 , a 8 , a 10 , a 11 是關鍵活動。
(3)求出 aoe 網中所有關鍵活動後,只要刪去 aoe 網中所有的非關鍵活動,即可得到 aoe 網的關鍵路徑。
這時從開始頂點到達完成頂點的所有路徑 都是關鍵路徑。乙個 aoe 網的關鍵路徑可以不止一條,如圖 7.21 的 aoe 網中有二條關鍵路徑, ( v 1 , v 2 , v 5 , v 7 , v 9 ) 和 ( v 1 , v 2 , v 5 , v 8 , v 9 ) 它們的路徑長度都是 16 。如圖 7.24 所示。
並不是加快任何乙個關鍵活動都可以縮短整個工程完成的時間,只有加快那些包括在所有的關鍵路徑上的關鍵活動才能達到這個目的。只有在不改變 aoe 網的關鍵路徑的前提下,加快包含在關鍵路徑上的關鍵活動才可以縮短整個工程的完成時間。
拓撲排序和關鍵路徑
拓撲排序 乙個無環的有向圖稱為無環圖 directed acyclic graph 簡稱dag圖。所有的工程或者某種流程都可以分為若干個小的工程或者階段,稱這些小的工程或階段為 活動 這些子程式之間存在一定的約束,其中某種子工程的開始必須在另一些子工程完成之後。因此dag圖表示乙個工程,其中有向邊表...
拓撲排序和關鍵路徑
文章出自 拓撲排序和關鍵路徑 拓撲排序 拓撲排序最大的用途就是判斷乙個有向圖是否有環,當然判斷還有一種方法就是floyd演算法。如果用鄰接表的話拓撲排序的時間複雜度是o n e 鄰接矩陣是o n 2 n表示頂點數,e表示邊數,floyd時間複雜度是o n 3 拓撲排序方法可分為無前趨的頂點優先的拓撲...
拓撲排序和關鍵路徑
include include include include includeusing namespace std struct node const int maxv 1010 vectorg maxv 鄰接表 int n,m,indegree maxv 頂點數 邊數 入度 ve是事件最早到達時...