dijstra最短路徑

路漫漫其修遠兮,吾將上下而求索。 
                ——屈原

          迪傑斯特拉算法的動態演示

  在最短路徑的求解算法中,迪傑斯特拉(Dijkstra)算法應該是非常出名的,但是對於初學者而言卻又很難理解爲什麼這個算法是對的,找到的就是最短路徑。下面博主參考了相關資料,和大家談談如何理解迪傑斯特拉算法。

一、鬆弛(relaxation)

  所謂“鬆弛”是從國外的文獻資料上的單詞“relaxation”直譯而來的,亦可以翻譯成“弛豫”。那麼,到底什麼是鬆弛呢? 
  我們先來看下面這張圖片。

這裏寫圖片描述

  上圖中,原來認爲頂點vivj的最短路徑爲虛線所標的路徑vi->vj。而當將vk這個頂點拉進vivj之間後,發現dist[i][k]dist[k][j]dist[i][j],即從頂點vi出發,先經過vi->vk這條路,再經過vk->vj這條路,最後抵達vj頂點的路徑長度比vi->vj這條路要短,所以放棄原來虛線的那條路,而選擇新發現的這條路。 
  上述過程就是所謂的“鬆弛”,即好像將原來“緊繃”的“弦”(路vi->vj)通過頂點vk將它“拉開”,也就“鬆了下來”。

二、(最優子結構)從vivj的最短路上所經過的頂點vk一定滿足vivk的路徑爲最短路

  標題中所給出的結論是顯然的。下面我們通過反證法做一些論證。

這裏寫圖片描述

  假設已知上圖中實線所示的路徑爲vivj的最短路徑,而現在又發現vivk之間還存在着另一條比vivk的實線路徑還要短的路徑,即虛線路徑。那麼vivk的最短路徑就應該是從vi出發,經過虛線路徑到達vk,再沿着實線路徑抵達vj。這與我們先前的假設矛盾!所以,從vivj的最短路上所經過的頂點vk一定滿足vivk的路徑爲最短路。

三、(貪心選擇性質)對於無負權環的圖G,若頂點v所對應的距離爲VU中頂點在距離表中的最小值,則源點到v的最短路已經找到

  上述結論中,V指圖G中的所有頂點集合,U指已經找到從源點出發至該點的最短路的頂點集合。 
  首先介紹距離表。所謂距離表,就是記錄當前求得的從源點vi到該點的最短路徑長度。 
  依然利用反證法論述上述結論。 
  假如該最小值所對應的頂點v的單源最短路徑並不是當前求得的路徑,那麼可以找到另外某個VU的其他頂點v通過鬆弛操作,使得sv的路徑更短。而由於sv的距離已經比sv的距離長,那麼無法通過鬆弛操作找到更短的路徑。 
  但是,上述論述都需要一個前提,就是圖中不含負權環

這裏寫圖片描述

四、迪傑斯特拉算法的運行過程

  下面,終於正式進入迪傑斯特拉算法的解釋。 
  首先,我們需要開兩個集合UVU,其中V爲圖G的所有頂點集合,U爲已經求得從源點vi到該點的最短路徑的那些頂點。 
  同時我們還要開一個表,來記錄當前求得的從源點vi到該點的最短路徑長度,即距離表。 
  初始時,集合U中只有源點vi,而VU中就是V{vi},表中就是vi到該頂點一步可達路徑的距離,若不存在一步可達,就記錄爲。 
  接着每一次循環都將距離表中最短距離所對應的頂點拉入集合U中,並利用新加入的頂點對VU中的頂點依次做鬆弛,若經過新頂點的路徑距離比原來的要小,則更新距離表中的值。 
  對於上一步驟的正確性,前文已經給出解釋。首先,認爲距離表中VU集合中的頂點所對應的距離值最小者所對應的頂點,即爲最新發現的從源點發出的至一點的最短路徑,那麼還未找到最短路徑的其他頂點的最短路勢必要經過這個頂點或者U中的其他頂點。 
  如此的循環下去直到所有頂點都被拉入集合U中爲止。 
  可以從下面的例子來理解上述過程。

這裏寫圖片描述

  下面,從距離表中找到距離最小的頂點2,然後將2號頂點加入集合U中,並且對1號頂點到VU集合中的頂點,通過2號頂點做鬆弛,將距離表更新。

這裏寫圖片描述

  在距離表中找到最小值30,將對應的4號頂點拉進集合U,對集合VU中的頂點再做一次鬆弛。

這裏寫圖片描述

  在距離表中找到最小值50,將對應的3號頂點拉進集合U,對集合VU中的頂點再做一次鬆弛。

這裏寫圖片描述

  再將5號頂點拉入集合U中,由於VU已經爲空,不需要再做新的更新。至此,算法結束,從源點至其他各個頂點的最短路徑都已經找到。

五、存在的問題

  由於上述更新的過程中,如果發現頂點vivj經過新加入的頂點vk所得到的路徑長度比原來的更短,就對距離表做修改。只要該頂點當前的距離是VU中頂點在表中數值的最小值,就認爲該頂點的最短路已經找到,而不會對其再做更新。即認爲:距離表中VU集合中的頂點所對應的距離值最小者所對應的頂點,即爲最新發現的從源點發出的至一點的最短路徑。而這個認爲並非總是成立。事實上,如果G中存在負權環,即存在一個圈,該圈上的權值之和爲負值,那麼每走一次圈,距離就會減小一些,那麼就不存在最小距離之說,因爲距離可以達到負無窮大。也就是說,距離表中所謂的“最小值”並非真正的最小值,我們總還是能夠找到比起更小的值。那麼算法正確性就沒了保證。

這裏寫圖片描述

  那麼,我們該怎麼面對帶有負權環的圖呢?歷史上,Richard Bellman和Lester Ford等人給出了他們的解決方案,稱爲Bellman-Ford算法,它可以幫助我們判斷G中是否存在負權環,同時在負權環不存在的情況下給出單源最短路徑。對於該算法,這裏不做過多介紹,大家可以去查閱相關資料學習。

參考資料:

[1] 最短路徑算法——Dijkstra(迪傑斯特拉)算法分析與實現(C/C++) 
[2] 算法(第4版),塞奇威克(Robert Sedgewick)、韋恩(Kevin Wayne)著

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章