1. 程式人生 > 其它 >資料結構和演算法學習筆記十:圖的拓撲排序和關鍵路徑

資料結構和演算法學習筆記十:圖的拓撲排序和關鍵路徑

一.拓撲排序簡介

  1.AOV網:在實際的一項工程中,往往會有一個或多個最終的目標,如果我們將這個最終的目標進行拆解,就能拆解出許多中間目標,完成這些目標之間是有先後順序的.如拍攝一部電影需要首先有劇本\有場地\有演職人員等,然後進行場景拍攝,最後經過後期製作\商業宣傳等最終上映.這些中間目標往往是有先後順序的,我們不可能還沒有進行場景拍攝就開始後期製作,不可能沒有場地就開始拍攝...如果將這些中間目標或活動使用一張有向圖表示出來,使用頂點代表活動,使用弧代表活動之間的先後次序,那麼這樣一張有向圖就可以稱為 AOV網(Activity On Vertex Network).AOV網是一張不存在環路的有向圖,它一定存在一個或多個出度為0和入度為0的頂點.

  2.拓撲序列:AOV網是一張沒有環路的有向圖,將其中的部分頂點排成一個序列,序列中任意兩個頂點A和B都滿足:若從A到B有一條路徑,則序列中A一定在B之前,那麼這條序列就稱為一個拓撲序列.

  3.拓撲排序:對一個有向圖構造拓撲序列的過程.

  4.拓撲序列的作用:拓撲序列可以這樣理解:如果某個工程中所有活動都必須逐個完成,不能同時做兩個活動,那麼拓撲序列就是這個工程的所有活動的完成次序.

二.拓撲排序演算法

  拓撲排序的思路是:找到一個入度為0的頂點,找到的入度為0的頂點及以其為尾的弧會被刪去,這個頂點被加入拓撲序列中...迴圈此過程直到所有頂點都被找完.既然要不斷尋找入度為0的頂點,那麼顯然使用鄰接表(連結串列中儲存頂點為頭的弧)實現圖是一個不錯的方法,只需在頂點資料結構中增加一個入度域,每次新增一條弧時將對應頂點的入度指標加一,在頂點被刪去後遍歷其鄰接表中的所有弧,每遍歷一條弧將相應的頂點的入度域減一即可.

  下面舉例說明:

  如圖,這是一個電影拍攝的AOV網(參考《大話資料結構》P271的示例圖),我們可以對其進行拓撲排序。

    1.入度為0的頂點只有“劇本初步完成”,所以它一定是拓撲序列中的第一個節點,刪去這個節點及以其為尾的弧;

    2.入度為0的頂點只有“電影製作啟動”,所以它作為拓撲序列中的第二個節點,刪去這個節點及以其為為的所有弧;

    3.此時入度為0的頂點有“導演確定”、“前期準備”、“投資確定”共三個,這三個頂點同時放入拓撲序列中作為第三到五個節點,這三個頂點之間的順序任意,然後刪去這些節點及以其為尾的弧;

    4.此時入度為0的頂點有“劇本完善”、“演職人員確定”、“場地確認”共三個,同樣放入拓撲序列中並將這些節點刪去;

    5.最後依次將“人員到位進駐場地”、“場景拍攝”、“後期製作及上映”三個節點逐個加入拓撲序列中並刪去。

    6.注意:將節點加入拓撲序列中是一個節點一個節點加入的,這裡為了簡便3、4步都直接將三個節點一次性加入,實際上不是這樣的,如按照“導演確定”、“劇本完善”、“前期準備”、“演職人員確定”、“投資確定”、“場地確認”這個順序將節點加入拓撲序列中也是可以的。

三.關鍵路徑演算法

  

  如圖所示,現在我們將弧的權值填入(隨機填的數值),其中權值代表工期,如“劇本初步完成”到“電影製作啟動”的弧權值為1,代表需要1天的時間進行“劇本初步完成”活動,之後才可以開始“電影製作啟動”活動。那麼我們現在怎麼確定整個專案的工期是多少天呢?

  如上圖所示,圖中每個頂點的下方都添加了一個紅色的數字代表最早開始時間,如“劇本初步完成”最早0天開始,因為需要一天的時間進行活動,所以“電影製作啟動”最早1天開始,同理,“前期準備”需要“電影製作啟動”進行3天時間,所以最早4天時開始...還可以注意到,“場地確認”需要“前期準備”2天和“投資確定”1天后才可以開始,而“投資確定”最早2天時開始,“前期準備”最早4天時開始,所以“場地確認”最早可能3天或6天時開始,顯然應該取最大值6天,其他的類似情況同理。最終我們得到了第16天時可以開始“後期製作及上映”活動,所以整個工程的工期是16天。那麼另一個問題是所有活動最晚啟動的時間怎麼得到呢?

  如上圖,我們再次使用藍色字型標出了每個活動的最晚開始時間。最晚開始時間需要使用最後一個活動的最早開始時間進行倒推。“後期製作及上映”最早16天時開始,最晚也應該是16天時開始,倒推回去“場景拍攝”最晚11天開始,因為“場景拍攝”需要進行5天后才能開始“後期製作及上映”。同樣地,像“導演確定”活動最晚開始時間推斷時會有歧義,因為“劇本完善”最晚8天時開始,而“導演確定”進行2天后就可以開始“劇本完善”了,也就是說“導演確定”最晚可以6天時開始;“演職人員確定”最晚7天時開始,而“導演確定”進行4天后可以開始“演職人員確定”,因此導演確定最晚3天時開始;顯然我們應該取6天和3天中的最小值,也就是說最晚3天時開始“導演確定”活動。現在我們可以得到那些工序是有冗餘時間的了。

  如上圖,我們用橙色數字在弧的下方註明了每一項活動進行的冗餘時間,如“投資確定”活動到“場地確認”活動中,投資確定最早2天開始,“場地確認”最晚8天開始,那麼開始“場地確認”活動前進行的“投資確定”活動的進行時間最多6天,實際只需要一天,因此有5天的冗餘時間。我們可以發現在整個AOE網中有很多活動的冗餘時間是0,也就是說這些活動必須準點開始準點結束,它們的任何延期都會影響整個工程的最終完成時間,這些冗餘時間為0的路徑就可以稱為工程的關鍵路徑。