單源最短路徑(Dijkstra) 貪心演算法

2021-06-23 03:40:18 字數 2136 閱讀 9692

dijkstra演算法是解單源最短路徑問題的貪心演算法。其基本思想是,設定頂點集合點集合s並不斷地做貪心選擇來擴充這個集合。乙個頂點屬於集合s當且僅當從源到該頂點的最短路徑長度已知。初始時,s中僅含有源。設u是g的其一頂點。把從源到u且中間只經過s中頂點的路稱為從源到u的特殊路徑,並用陣列distance記錄當前每個頂點所對應的最短特殊路徑長度。dijkstra演算法每次從v-s中取出具有最短特殊路長度的頂佔,distance就記錄了從源到所有其它頂點之間最短路徑長度。

例如下圖中的有向圖,應用dijkstra演算法計算從源頂點1到其它頂點最短路徑的過程列表在下表中。

演算法過程描述:

**中預設選取的起始頂點為1頂點,所以本問題就轉化為求解1頂點到2, 3, 4, 5這幾個頂點的最短路徑。首先初始條件列出1頂點到2, 3, 4, 5各個頂點的距離,這個距離直接在圖的儲存鄰接矩陣中得到,選取距離最近的乙個也就是2頂點加入集合s,下面要進行的是比較關鍵的一步,這個時候應該去獲取3, 4, 5三個頂點到集合s的最短距離(從1頂點出發,可以經過s中的任意頂點):將1到2頂點的距離加上2到各個點的距離,然後用這個距離來同1到各個頂點的距離相比較,誰小就取誰,以此類推,然後每次取distance最小的值進入集合s。

這樣下去,distance中存放的就是每個頂點到集合s的最短距離,比如當前的集合只有1, 2,按照規則頂點4應該入選進集合s,因為distance[3]沒有入選集合的頂點中對應的distance最小的頂點。現在需要計算3和5到新集合s=的最短距離,這個時候就只需要將distance[2]和distance[4]中的值(現在這裡面的值表示集合s=到頂點3和5頂點的最短距離),但是現在集合中加入了頂點4,怎麼計算?計算方法如下:

distance[3] + 鄰接矩陣中頂點4到頂點3的距離 < distance[2] ?

distance[3]:(頂點4到s=的最短距離)

distance[2]: (頂點3到s=的最短距離)

如果這個小於成立,那麼很明顯新的集合到頂點3的最小距離應該是先從s=到頂點4的最短距離,然後再從頂點4到頂點3。

由於每一次的比較都是在上一次集合的最優結果中計算的,所以新計算出來的頂點3到集合s=的最短距離也是全域性最優的。

對應的c語言**如下:

#include #define m	65535 //無窮大

#define n 5 //頂點數

//dijkstra演算法函式,求給定頂點到其餘各點的最短路徑

//引數:鄰接矩陣、出發點的下標、結果陣列、路徑前一點記錄

void dijkstra(int cost[n], int v0, int distance, int prev)

} // if 語句體結束,j迴圈結束

} // i迴圈結束

}// 輸出最短路徑

// 引數:路徑前一點記錄、出發點的下標、到達點下標

void printprev(int prev,int v0,int vn)

else break;

}//輸出路徑,陣列逆向輸出

for(i=n-1; i >= 0; i--)

}printf("-->v%d", vn+1);

}//主函式

int main()

; //給出有向網的鄰接矩陣

int cost[n][n]=,,,

,,};int distance[n]; //存放求得的最短路徑長度

int prev[n]; //存放求得的最短路徑

int i;

//呼叫dijkstra演算法函式,求頂點v1到其餘各點的最短路徑

//引數:鄰接矩陣、頂點數、出發點的下標、 結果陣列

dijkstra(cost, 0, distance, prev);

for(i=0; i < n; i++)

return 0;

}

程式執行結果截圖:

參考文章:

Dijkstra 單源最短路徑

演算法思想 輔助陣列dis i 表示當前源頂點到i的最短路徑。dis i 在程式未結束前,類似於動態規劃,可更新以取得最小值 陣列path用來記錄路徑 首先初始化令dis i 為edge v0 i v0為源頂點 然後選擇離源頂點最小的路徑,加入到構造最短路徑的點集合中,然後看是否可以更新dis i ...

Dijkstra 單源最短路徑

演算法思想 輔助陣列dis i 表示當前源頂點到i的最短路徑。dis i 在程式未結束前,類似於動態規劃,可更新以取得最小值 陣列path用來記錄路徑 首先初始化令dis i 為edge v0 i v0為源頂點 然後選擇離源頂點最小的路徑,加入到構造最短路徑的點集合中,然後看是否可以更新dis i ...

Dijkstra單源最短路徑

dijkstra單源最短路徑 給定乙個帶權有向圖g v,e 其中每條邊的權是乙個非負實數。另外,還給定 v 中的乙個頂點,稱為源。現在我們要計算從源到所有其他各頂點的最短路徑長度。這裡的長度是指路上各邊權之和。這個問題通常稱為單源最短路徑問題。下面給出兩個計算單源最短路徑的模板。dijkstra 簡...