演算法導論 單元最短路徑

2021-09-20 05:50:33 字數 2796 閱讀 7796

單源最短路徑問題是指,給定乙個圖g=(v,e),希望找到從給定源結點s到每個節點v的最短路徑。單源最短路徑問題可以用來解決很多最短路徑的變體。

單目的地最短路徑問題:找到從每個結點v到給定目的地結點t的最短路徑。將圖的每條邊翻轉,這個問題可以轉換為單源最短路徑問題。

單結點對最短路徑問題:找到從給定結點u到給定結點v的最短路徑。如果已經解決了u的單元最短路徑問題,則該問題已經解決。

在單源最短路徑問題中,根據圖的性質不同有不同的解決方案。主要的性質有:是有向圖還是無向圖,是權重圖還是單位圖,有無負權重的邊,是否有環。

dijkstra演算法解決的是非負權重有向圖上的單源最短路徑問題。演算法邏輯為維持乙個結點集合s,集合中每個結點之間的最短路徑已經被找到,重複從集合v-s中選擇與源結點r之間最短路徑估計最小的結點u加入到s,然後對所有從u出發的邊檢查r到u的距離加上該邊的距離是否小於該邊另乙個結點原本的最短路徑估計。

如圖(a)初始狀態,s是源結點,加入到集合s中

(b)檢查s出發的路徑(s,t)和(s,y)更新y和t的最短路徑估計

(c)在剩下結點中選擇最短路徑估計最小的結點y,然後檢查從y出發的路徑(y,t)+(s,y)=8<10,更新t的距離為8,同樣對x和z也進行同樣的操作,結束後y加入到s中

(d)接下來選擇z結點,(z,s)+7=14>s,所以s保持不變,而(z,x)+6=13<14,x的值更新為13,然後將z加入到s中。

(e)-(f)的操作同上,不再做詳細描述。最終所有點都加入到了s中。

為了完成演算法,我們需要儲存每個結點的最短路徑估計和他們的前驅結點來輸出最終路徑,同時需要乙個最小優先佇列來儲存v-s中結點的最短路徑估計排序,否則需要遍歷v-s中的結點來選擇出最短的那個。直接遍歷所有邊的演算法複雜度為o(v^2),若使用最小二叉堆來儲存優先佇列則複雜度可以降低為o((v+e)l**)。

1 #include2

using

namespace

std;

3#define size 10

4#define infi 1000056

int g[size][size];//

鄰接矩陣,引數初始化略

7int dist[size];//

與根間的距離估計

8bool visit[size];//

是否被訪問過910

void dijkstra(int

root)

17 dist[root] = 0;18

for(i = 0; i )24}

25for(j = 0; j < size; j++)

29 visit[min] = true;30

}31 }

該演算法可以解決負權重邊的圖,演算法返回乙個布林值,表明是否存在乙個從源節點可以到達的權重為負的環路,若存在則演算法將告訴我們不存在解決方案,因為這個環路的存在會導致出現距離為負無窮的點。

演算法需要進行|v|-1次迴圈,每次迴圈按照同樣的順序對所有邊進行鬆弛,結束後檢查是否存在權重為負的環路。演算法複雜度為o(ve),因此該演算法在處理密集圖時效率會降低,總體效率不如dijkstra演算法。

如圖所示每一次鬆弛邊的順序都是(t,x) (t,y) (t,z) (y,x) (y,z) (z,x) (z,s) (s,t) (s,y)。源結點為s,加了陰影的邊表示前驅路徑。

(a)       更新源結點的距離為0

(b)       按照順序,僅(s,t) (s,y)可以更新結點的值,t=6 y=7

(c)       (t,z) (y,x)可以更新z和x的值

(d)       (x,t)可以更新t的值

(e)       本次迴圈沒有可以更新的值,檢查不存在權值為負的環返回true

1 #include2

using

namespace

std;

3#define size 10

4#define infi 1000056

int g[size][size];//

鄰接矩陣,引數初始化略

7int dist[size];//

與根間的距離估計

8int p[size];//

前驅結點910

void bellmanford(int

root)

15 dist[root] = 0;16

for(i = 0; i < size - 1; i++)24}

25}26for(i = 0; i < size; i++)31}

32 }

使目標函式值最大。在乙個差分約束系統中,線性規劃矩陣a的每乙個行包括乙個1和乙個-1,其他所有項都是0,每個限制條件變為不等式xj-xi≤bk。

如圖所示的矩陣和向量可以表示為8個簡單不等式,要求出一組可行解。以x作為結點,後面的約束值作為路徑權重,可以畫出一張約束圖

單元最短路徑 SPFA演算法

2012 09 16 19 12 37 標籤 分類 圖論 介紹 單源最短路徑的演算法最常用的是dijkstra,些演算法從時間複雜度來說為o n 2 但是面對含有負權值的圖來說就無能為力了,此時dellman ford演算法就有用了,這咱演算法是採用的是動態規化的思想,但是1994年西南交通大學段凡...

單元最短路徑問題

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

單元最短路徑 spfa

時間複雜度最差為o mn 與bellman ford相同 適用範圍 負權的單源最短路,或者判斷負環。稀疏圖 稠密圖用dijkstra演算法 可以記錄最短路到目標的路徑。原理 將起點放入佇列,用隊首的點不斷更新所連邊上的點,更新後將未在佇列中的放入佇列,直到隊列為空。若乙個點被放入佇列超過n 點的個數...