最短路徑演算法

2021-10-13 18:56:37 字數 1513 閱讀 6679

兩種最短路徑演算法:dijkstra和bellman

問題:在一張圖中,從一點出發到大其他個點的最短路徑。

思路:假設a到b之前的直達路徑是10,如果求a到b的最短路徑,就需要抄近路,比如加個c,a->c->b,看這條路徑是不是比10小。

然後是這個c怎麼選擇。如下圖,求取頂點1到其它頂點的最短路徑。

除去1,還有五個頂點,先列出1到其它頂點的距離,在不經過其它頂點的情況下的距離,無法直達的用正無窮表示,這裡用00代替,可以得到乙個距離陣列distant=,分別表示頂點1到(i+1)頂點的距離,其中i為陣列中元素的下標;

對distan排序,除去頂點1之外,找出1到其它頂點的最小距離,這裡可以看到1到2最短,距離為1;

用(2)中獲得的最小值當做c,做為1到其它頂點的中間頂點,看是否縮短距離,如果縮短了距離就將跟新後的距離更新到distant陣列中。比如,1到4本來是沒有知道路徑的,如果以2為中間點,可以到達,距離為(1+3);1到3有可以直達的路徑,如果以2為中間點,距離變為(1+9),要小於本來1到3直達的距離;

按照上述思路查詢所有頂點,查詢一遍之後,distant資料更新為;

對更新後的陣列distant繼續進行(2)(3)操作,迴圈進行。迴圈的次數是(n-1),其中n為頂點總個數;

注意:dijkstra演算法應用的前提是所有邊的權重都為正,只有當所有邊都為正的時候,上述遍歷結果才能確保當前路徑是最短的,如果有負邊,比如上圖中4到3權重為-4,1->2->4->3要小於1->2->3,但如果在演算法流程的(2)中,已經認為1->2->3是1到3的最短經,就不會在更新1到3的distant,導致演算法最後求得的最短路徑並不是最短。

時間複雜度:最壞情況下的時間複雜度為n*n,n為頂點個數。

時間複雜度優化:有幾個優化方向,演算法需要找到最小值,用最小堆實現可以將時間複雜度從o(n)優化到o(logn)。將頂點個數記做n,邊數記做m,m通常要小於n*n,也就是稀疏圖,稀疏圖出採用鄰接表表示效率更高。最終的時間複雜度可優化為o((m+n)logn)。

該演算法可以應用於負權邊的問題。

bellman演算法基於這樣的乙個想法,如果乙個圖中的節點個數為n,m條邊,那麼從乙個頂點到另乙個頂點的最短路徑包含邊的範圍是[1, n-1]。然後可以檢查某一條邊再加上跟他相連的另一條邊之後能不能讓本來的路徑變短,變短了就更新。

核心**如下

for (int p = 1; p < num_point - 1; ++p) }}

該演算法每輪迭代都試探所有可能的邊,就不存在dijkstra演算法中的問題。

時間複雜度:該演算法的時間o(mn)。

時間複雜度優化:外層迴圈是在遍歷幾條路徑,某些頂點會不再更新的,這樣的話就沒必要繼續計算,可以之間跳過。這時可以有佇列來記錄這些不再更新的點。具體實現參照**。要注意的是,這種方法的最差效能仍然是o(mn)。

原始碼:

最短路徑演算法 最短路

在每年的校賽裡,所有進入決賽的同學都會獲得一件很漂亮的t shirt。但是每當我們的工作人員把上百件的衣服從商店運回到賽場的時候,卻是非常累的!所以現在他們想要尋找最短的從商店到賽場的路線,你可以幫助他們嗎?input 輸入包括多組資料。每組資料第一行是兩個整數n m n 100,m 10000 n...

最短路徑演算法

floyd演算法 012345 001 54 1108 1 2 801 3 3 1035 45 302 5413520 floyd 演算法過程描述如下 首先 以邊集 初始化,得到所有的直接連通代價 依次考慮第 k個結點,對於 中的每乙個 i j 判斷是否滿足 s i j s i k s k j 如果...

最短路徑演算法

個人覺得下面 有代表性 最短路徑演算法原始碼 vb 本人載 開發gis,遊自編的最短路徑查詢程式,速度特快,3萬節點,35000條路全部遍歷,只需1秒。現將最短路徑的思路告訴大家,希望大家在優化,並用不同語言編制,我正在學delphi,準備用delphi做成庫,本例以由拓撲關係的arc info 檔...