單源最短路徑 Dijkstra演算法

2021-10-12 12:35:09 字數 2120 閱讀 9675

寫在前面:好久沒看圖論了,今天寫作業的時候發現我已經忘記了。俗話說的好,好記性不如爛筆頭,我翻了翻之前的筆記,竟然沒有關於dijkstra的(手動狗頭)。趕緊連夜寫了一篇部落格,只為勾引我對dijkstra的些許記憶。

從乙個頂點到其餘各頂點的最短路徑演算法,解決的是有權圖(不存在負權邊)中最短路徑問題

它是由e.w.dijkstra提出的一種按照路徑長度遞增的次序

分別產生到各頂點最短路徑的貪心演算法。

該演算法把帶權圖的的所有頂點分成兩個集合s和v-s。集合s中存放的是已經找到最短路徑的頂點。v-s中存放未找到最短路徑的頂點。演算法按照路徑長度遞增的次序。逐一將v-s中的元素移動到s中。直至v-s為空。

其中,用到乙個非常重要的原理:如果當前v0到vi的最短路徑已經找到,那該條路徑也一定是v0到路徑中所有點的最短路徑。換句話說,如果要找v0到vi的最短路徑,那麼在vi之前的i-1個頂點肯定已經找到最短路徑了,即i-1個頂點都在集合s中。

如圖中,0-4的最短路徑為0-1-7-8-2-5-4.那麼從v0到v8的最短路徑一定是0-1-7-8.

我們以8號結點為例,進行證明:

假設v0-v8的最短路徑是0-7-6-8,那麼也就說明圖中紅色路徑的長度小於0-1-7-8的長度。

那麼從起點0-4的最短路徑就是下圖中的紅色所示。

這與前提不符合,即假設不合理,所以從v0到v8的最短路徑一定是0-1-7-8.

dijkstra演算法按照從給定起點到圖中頂點的距離,順序求出最短路徑。首先求出從起點到最接近點的頂點之間的最短路徑。然後求出第二近的,一次類推。推而廣之,在第i次迭代開始以前,該演算法已經確定了i-1個頂點的最短路徑。假定上一次(第i-1次迭代)加入集合s的頂點為t。那麼在集合v-s中,與a相鄰的頂點集合稱為「邊緣頂點」,他們作為候選物件。而dijkstra演算法可以從這些候選物件中選出下乙個最接近源點v0的頂點,並把它移動到v-s集合中。

將所有的頂點分為兩部分:已知最短路徑的頂點集合s和未知最短路徑的頂點集合v-s。可考慮用book陣列實現,book[i]=1,可表示在s中,book[i]=0,則表示在s-v中。

初始化設定源點v0到自己的最短路徑為0.若存在有源點能直接到達的頂點i,就把v0-vi的最短路徑設定為對應的長度。同時把其他頂點的最短路徑設定為∞。同時book陣列清零。

在集合s-v中選擇乙個距離遠點最近的頂點i,加入到集合s中。並考察所有以i為起點的邊,對每一條邊進行鬆弛操作。例如存在一條從頂點u到頂點v的邊,則可通過u拓展一條從s到v的路徑即s -> u -> v,這條路徑的長度為dis[ u ]+e[ u ][ v ],如果這個值比dis[ v ]的值要小,我們可以用新值替代當前dis[ v ]中的值

如此重複第三步,如果集合v-s為空,則結束。最終dis陣列中的值就是源點到各點的最短路徑

void

dijkstra

(int s)

//s為源點即起點

} book[u]=1

;//頂點u已經確定最短距離,移入集合s,標記為1

//鬆弛:遍歷頂點u的邊緣頂點,借助剛確定的u頂點作為中轉點重新整理最短距離

for(j =

1;j <= n;j++)if

(e[u]

[j]< inf)

//如果u點到j點有路

//源點s到j點的距離大於借助u點中轉的距離(就是源點到u的距離加u到j的距離)

if(dis[j]

> dis[u]

+ e[u]

[j])

dis[j]

= dis[u]

+ e[u]

[j];

//更新源點到j頂點的最短距離

}}

tips:個人回憶小部落格,不足之處,希望大佬糾正。

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 簡...