七、圖的應用
7.1、兩種常用的活動網絡( Activity Network):
① AOV網(Activity On Vertices)—用頂點表示活動的網絡
AOV網定義:若用有向圖表示一個工程,在圖中用頂點表示活動,用弧表示活動間的優先關系。Vi 必須先於活動Vj 進行。則這樣的有向圖叫做用頂點表示活動的網絡,簡稱AOV。
② AOE網(Activity On Edges)—用邊表示活動的網絡
AOE網定義:如果在無環的帶權有向圖中,用有向邊表示一個工程中的活動,用邊上權值表示活動持續時間,用頂點表示事件,則這樣的有向圖叫做用邊表示活動的網絡,簡稱AOE。
7.2、AOV網絡的用途---拓撲排序
我們經常用有向圖來描述一個工程或系統的進行過程。一般來說,一個工程可以分為若干個子工程,只要完成了這些子工程,就可以導致整個工程的完成。
AOV網絡若用於教學計划的制定,可以解決:哪些課程是必須先修的,哪些課程是可以並行學習的。
拓撲排序
什么叫拓撲排序?
按照有向圖給出的次序關系,將圖中頂點排成一個線性序列,對於有向圖中沒有限定次序關系的頂點,則可以人為加上任意的次序關系。由此所得頂點的線性序列稱之為拓撲有序序列
如何進行拓撲排序?
一、從有向圖中選取一個沒有前驅的頂點(即入度為零的頂點),並輸出之;
二、從有向圖中刪去此頂點以及所有以它為尾的弧(即弧頭頂點的入度減1);
重復上述兩步,直到
全部頂點均已輸出,拓撲有序序列形成,拓撲排序完成;
或圖中還有未輸出的頂點,但已跳出處理循環。這說明圖中還剩下一些頂點,它們都有直接前驅,再也找不到沒有前驅的頂點了。這時AOV網絡中必定存在有向環。
序號 1、2、3、4、5、6、7 前件的序號<后件的序號,合乎拓撲排序的要求
使用鄰接矩陣實現拓撲排序:
算法的執行步驟:
1、找到全為零的第j 列,輸出j
2、將第j 行的全部元素置為零
3、找到全為零的第k列,輸出k
4、將第k行的全部元素置為零 …………………
反復執行3、4;直至所有元素輸出完畢。
使用鄰接表實現拓撲排序:
算法的執行步驟:
1、用一個數組記錄每個結點的入度。將入度為零的結點進棧。
2、將棧中入度為零的結點V輸出。
3、根據鄰接表找到結點V的所有的鄰接結點,並將這些鄰接結點的入度減一。如果某一結點的入度變為零,則進棧。
4、反復執行 2、3;直至棧空為止。 …………………
次序執行結束,如果輸出結點數等於圖的結點總數,則有向圖無環,否則有向圖有環。
CountInDegree(G,indegree); //對各頂點求入度 InitStack(S); for ( i=0; i<G.vexnum; ++i) if (!indegree[i]) Push(S, i); //入度為零的頂點入棧 count=0; //對輸出頂點計數 while (!EmptyStack(S)) { Pop(S, v); ++count; printf(v); for (w=FirstAdj(v); w; w=NextAdj(G,v,w)){ --indegree(w); // 弧頭頂點的入度減一 if (!indegree[w]) Push(S, w); //新產生的入度為零的頂點入棧 } } if (count<G.vexnum)printf(“圖中有回路”)
|
7.3AOE網絡的用途:---確定關鍵路徑
常用於大型工程的計划管理。利用AOE網絡可以解決以下兩個問題:
(1) 完成整個工程至少需要多少時間。(假設網絡中沒有環)?
(2) 為縮短完成工程所需的時間, 應當加快哪些活動? 或者說,哪些活動是影響工程進度的關鍵?
問題:假設以有向網表示一個施工流圖,弧上的權值表示完成該項子工程所需時間。
問:哪些子工程項是“關鍵工程”?
即:哪些子工程項將影響整個工程的完成期限的。
例設一個工程有11項活動,9個事件
事件V1——表示整個工程開始
事件V9——表示整個工程結束
(1) 完成整項工程至少需要多少時間?
(2) 哪些活動是影響工程進度的關鍵?
關鍵路徑
- 在AOE網絡中, 有些活動順序進行,有些活動並行進行。
- 從源點到各個頂點,以至從源點到匯點的有向路徑可能不止一條。這些路徑的長度也可能不同。完成不同路徑的活動所需的時間雖然不同,但只有各條路徑上所有活動都完成了,整個工程才算完成。
- 完成整個工程所需的時間取決於從源點到匯點的最長路徑長度,即在這條路徑上所有活動的持續時間之和。這條路徑長度最長的路徑就叫做關鍵路徑(Critical Path)。
整個工程完成的時間為:從有向圖的源點到匯點的最長路徑。
關鍵活動:該弧上的權值增加 將使有向圖上的最長路徑的長度增加。關鍵活動的最早開始時間 =關鍵活動的最遲開始時間
構造關鍵路徑的方法:要用到拓撲排序和逆拓撲排序
事件發生時間的計算公式:
ve(源點) = 0; ve(k) = Max{ve(j) + dut(<j,k>)}
vl(匯點) = ve(匯點); vl(j) = Min{vl(k) – dut(<j, k>)}
開始vl=18
假設第i條弧為 <j,k>, 則 對第i項活動言
“活動(弧)”的最早開始時間 ee(i): ee(i) = ve(j);
“活動(弧)”的最遲開始時間 el(i): el(i) =vl(k)–dut(<j,k>);
算法描述
• 輸入頂點和弧信息,建立其鄰接表
• 計算每個頂點的入度
• 對其進行拓撲排序
排序過程中求頂點的Ve[i]
將得到的拓撲序列進棧
• 按逆拓撲序列求頂點的Vl[i]
• 計算每條弧的e[i]和l[i],找出e[i]=l[i]的關鍵活動