加權有向圖問題2----多源最短路徑問題(Floyd算法)和關鍵路徑算法

Floyd算法

Floyd算法又稱爲插點法,是一種利用動態規劃的思想尋找給定的加權圖中多源點之間最短路徑的算法。java

Floyd算法可以處理帶負權重的邊的有向圖但不能包含負權重環。算法

算法思想:

從起始頂點開始,依次加入一個頂點,每加入一個頂點,更新一下各條最短路徑長度。各條最短路徑長度保存在一個二位數組中。數組

算法實現:

for (int i = 0; i < V; i++) {
    for (int v = 0; v < V; v++) {
        if (edgeTo[v][i] == null) continue;  // 優化
        for (int w = 0; w < V; w++) {
            if (distTo[v][w] > distTo[v][i] + distTo[i][w]) {
                distTo[v][w] = distTo[v][i] + distTo[i][w];
                edgeTo[v][w] = edgeTo[i][w];
            }
        }
        // 檢查負循環
        if (distTo[v][v] < 0.0) {
            hasNegativeCycle = true;
            return;
        }
    }
}

關鍵路徑算法

優先級限制下的並行任務調度:給定一組須要完成的任務和每一個任務所須要的時間,以及一組關於任務完成的前後次序的優先級限制。在知足條件的前提下應該如何在若干相同的處理器上安排任務並在最短的時間內完成任務?優化

「關鍵路徑」算法能夠在線性時間內解決此問題。這個問題與無環加權有向圖的最長路徑問題是等價的。spa

爲了設計求關鍵路徑的動態規劃算法,如今定義三個術語設計

事件i可能最先發生的時間earliest(i): 是指從開始結點s到結點i的最長路徑的長度。code

事件i容許的最遲發生時間latest(i): 是值不影響效益的條件下,事件i容許發生的最晚時間。排序

關鍵活動: 處於關鍵路徑上的活動是關鍵活動,它必須準時啓動,不然就會使任務延期。事件

算法實現:

earliest()計算方法:

  • earlist(0) = 0
  • earlist(j) = max{earlist(i) + w(i,j)}    0<j<V, i∈P(j)   注:P(j)是拓撲圖中與頂點j直接相鄰的前一頂點集

latest()計算方法:

  • latest(V-1) = earliest(V-1)
  • latest(i) = min{latest(j) - w(i,j)}   0<=i<V-1,j∈S(i)    注:S(i)是拓撲圖中與i直接相鄰的後一結點集

關鍵活動計算方法:

若latest(j) - earliest(i) = e.weight (e爲頂點i和j之間的有權邊),則邊e是關鍵活動。對於關鍵路徑上的每個關鍵結點i,都有latest(i) = ealiest(i).get

算法步驟:

  1. 確認有向圖G是無環圖,並進行拓撲排序;
  2. 按拓撲次序計算earliest(i), 0<=i< V-1;
  3. 按逆拓撲排序計算latest(i), 0<=i< V-1;
  4. 計算latest(j) - earliest(i),判斷是否爲關鍵活動。
相關文章
相關標籤/搜索