【圖(下)】拓撲排序
阿新 • • 發佈:2018-11-22
1、舉例說明:計算機專業排課
說明:學C1,C2是不需要提前學別的課程的,學C3則需要提前學C1,C2。
把課程列表轉換為圖,其中頂點代表課程,則從V到W有一條邊代表:V是W的預修課程
2、拓撲排序
-
拓撲序
:如果圖中從V到W有一條有向路徑,則V一定排在W之前。滿足此條件的頂點序列稱為一個拓撲序 - 獲得一個拓撲序的過程就是
拓撲排序
- AOV如果有
合理的
拓撲序,則必定是有向無環圖
(Directed Acyclic Graph, DAG)
3、演算法
void TopSort()
{
for (cnt = 0; cnt < |V| ; cnt++)
{
V = 未輸出的入度為0的頂點;// O(|V|)
if (這樣的V不存在)//外迴圈沒結束已經找不到入度為0的頂點了,有環
{
Error(“圖中有迴路”);
break;
}
輸出V,或者記錄V的輸出序號;
for (V 的每個鄰接點W)
Indegree[W]––;//相當於去掉從V到W的邊
}
}
在TopSort函式中,如果外迴圈還沒結束,就已經找不到“未輸出的入度為0的頂點”,則說明圖中必定存在迴路。
時間複雜度:T = O( |V|2 )
4、聰明的演算法
隨時將入度變為0的頂點放到一個容器裡
void TopSort()
{
for (圖中每個頂點V)
if (Indegree[V] == 0)
Enqueue(V, Q);
while (!IsEmpty(Q))
{
V = Dequeue(Q);
輸出V,或者記錄V的輸出序號; cnt++;//計數器增加
for (V 的每個鄰接點W)//將V放入容器,V發出的邊斷開,V的鄰接點入度減1
if (––Indegree[W] == 0)
Enqueue(W, Q);
}
if (cnt != |V| )
Error(“圖中有迴路”);
}
隨時將入度為0的節點放入容器中,每次從容器中取出元素,保證都是入度為0。
時間複雜度:每個點被訪問一遍,每條邊訪問一遍
T = O( |V| + |E| )
此演算法可以用來檢測有向圖是否DAG(有向無環圖Directed Acyclic Graph)
5、關鍵路徑問題
-
AOE (Activity On Edge)
網路
一般用於安排專案的工序
每條邊代表一個工序或者一個活動
邊表示活動,頂點表示到達這個頂點時,活動結束了。
頂點的上面部分表示這項工作最早在什麼時間完成,下面的表示這項工作最晚什麼時間開始。
機動時間:不用那麼趕工期,以頂點0到頂點2為例,最早第0天開始工作,最晚第六天完成,而完成這項工作只需要4天時間,就有2天的機動時間。
關鍵路徑:由絕對不允許延誤
的活動組成的路徑