Dijkstra最短路徑算法


Dijkstra最短路徑算法

首先描述一下問題:給定一個有向圖G和源點v,求v0到G中某個頂點u的最短路徑。限定各邊上的權值大於或等於0。

算法的基本思想很簡單:所有的頂點,按照它到源點v的距離,客觀上存在一個從小到大的順序,我們只要按照這個順序找下去,總有一步會找到目標頂點u,而此時的距離就是u到源點v的距離。

想法簡單,但關鍵是怎么按照“客觀存在的大小順序”計算各點到源點v的距離呢?我們先簡單思考一下,按照距離v的遠近順序,v一定是排第一的,然后呢,排第二的一定是和v直接相連的點吧,否則總有一個點介於排第二的點和v之間,而它到v的距離肯定也比第二到v的距離近,那這個第二就有些名副其實了。比較麻煩的是,排第三的點在哪里?利用遞歸的想法就會發現,排第三的點應該從那些和v直接相連,或者和第二名直接相連的點中去尋找,否則第三名就會名副其實了。總結一下,需要找第n個點時,只需要在那些和前n-1個點直接相連的點里面找就行了。

Dijkstra算法的具體實現方法為:

1.設置兩個頂點的集合T和S:

a) S中存放已找到最短路徑的頂點,初始時,集合S中只有一個頂點,即源點v0;

b) T中存放當前還未找到最短路徑的頂點;

2.在T集合中選取當前長度最短的一條最短路徑(v0,…,vk),從而將vk加入到頂點集合S中,並修改源點v0到T中各頂點的最短路徑長度;重復這一步驟,直到所有的頂點都加入到集合S中,算法就結束了。

下面給個用Dijkstra計算最短路徑的例子

 

 

1)首先求出長度最短的一條最短路徑,即頂點0到頂點2的最短路徑,其長度為5,其實就是頂點0到其他各頂點的直接路徑中最短的路徑(v0→v2)。

2)頂點2的最短路徑求出來以后,頂點0到其他各頂點的最短路徑長度有可能要改變。例如從頂點0到頂點1的最短路徑長度由∞縮短為20,從頂點0到頂點5的最短路徑長度也由∞縮短為12。這樣長度次短的最短路徑長度就是在還未確定最終的最短路徑長度的頂點中選擇最小的,即頂點0到頂點5的最短路徑長度,為12,其路徑為(v0→v2→v5)。

3)頂點5的最短路徑求出來以后,頂點0到其他各頂點的最短路徑長度有可能要改變。例如從頂點0到頂點3的最短路徑長度由30縮短為22,從頂點0到頂點4的最短路徑長度也由∞縮短為30。這樣長度第三短的最短路徑長度就是在還未確定最終的最短路徑長度的頂點中選擇最小的,即頂點0到頂點1的最短路徑長度,為20,其路徑為(v0→v2→v1)。

4)此后再依次確定頂點0到頂點3的最短路徑(v0→v2→v5→v3),其長度為22;以及頂點0到頂點4的最短路徑(v0→v2→v1→v4),其長度為28。



看完就懂了!一篇搞定圖論最短路徑問題

最常見的問題——單源最短路

傳說中如雷貫耳的“單源最短路”應該是做題中最常見到的問題了。也即,指定源點,求它到其余各個結點的最短路

比如給出這張圖,假設把1號結點作為源點。

 

 

還是用數組dis來存1號到其余各點的初始路程:

既然是求最短路徑,那先選一個離1號最近的結點,也就是2號結點。這時候,dis[2]=1 就固定了,它就是1到2的最短路徑。這是為啥?因為目前離1號最近的是2號,且這個圖的所有邊都是正數,那就不可能能通過第三個結點中轉使得距離進一步縮短了。因為從1號出發已經找不到哪條路比直接到達2號更短了。

選好了2號結點,現在看看2號的出邊,有2->3和2->4。先討論通過2->3這條邊能否讓1號到3號的路程變短,也即比較dis[3]和dis[2]+e[2][3]的大小。發現是可以的,於是dis[3]從12變為新的更短路10。同理,通過2->4也條邊也更新下dis[4]。

松弛完畢后dis數組變為:

接下來,繼續在剩下的 3 4 5 6 結點中選一個離1號最近的結點。發現當前是4號離1號最近,於是dis[4]確定了下來,然后繼續對4的所有出邊看看能不能做松弛。

balabala,這樣一直做下去直到已經沒有“剩下的”結點,算法結束。

這就是Dijkstra算法,整個算法的基本步驟是:

  1. 所有結點分為兩部分:已確定最短路的結點集合P、未知最短路的結點集合Q。最開始,P中只有源點這一個結點。(可用一個book數組來維護是否在P中)
  2. 在Q中選取一個離源點最近的結點u(dis[u]最小)加入集合P。然后考察u的所有出邊,做松弛操作。
  3. 重復第二步,直到集合Q為空。最終dis數組的值就是源點到所有頂點的最短路。

 

Dijkstra是一種基於貪心策略的算法。每次新擴展一個路徑最短的點,更新與它相鄰的所有點。當所有邊權為正時,由於不會存在一個路程更短的沒擴展過的點,所以這個點的路程就確定下來了,這保證了算法的正確性。

但也正因為這樣,這個算法不能處理負權邊,因為擴展到負權邊的時候會產生更短的路徑,有可能破壞了已經更新的點路程不會改變的性質。

於是,Bellman-Ford算法華麗麗的出場啦。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM