Dijkstra迪傑斯特拉演算法 C 實現

2021-10-06 05:29:12 字數 2786 閱讀 3444

迪傑斯特拉演算法本質上是乙個貪心演算法,通過不斷迭代取得區域性最優解的方法,最終找到整體的最優解。迪傑斯特拉演算法主要用於在有權圖中計算出各節點到初始節點的最短路徑。在接下來的分析中我會使用的有權圖如下 :

其中,abcde就是我們需要遍歷的節點,連線節點的弦上的數字表示了兩節點之間的"距離",或稱之為權重,消耗。需要注意的幾點是 :

迪傑斯特拉演算法適用的有權圖中,節點之間的權重不要求是雙向的,即 a-> b的權重和 b->a 的權重不要求相同。換而言之,有權圖中節點之間的連線可以是單向的,或者在兩個方向權重有所不同的。

迪傑斯特拉演算法適用的有權圖中,節點間連線的權重值不能是負值。

了解了迪傑斯特拉演算法的一些注意點之後,我們下面來重點解釋演算法的實現。之前我們已經提到了,迪傑斯特拉演算法多用於解決最短路徑問題,對應上述有權圖就是計算出所有節點到初始節點的最短距離。在下述例子中,我們預設使用a作為初始節點,目標就是找出所有節點到a的最短距離以及所經過的路徑。

首先我們需要兩個列表,乙個visited列表用於存放已經遍歷過其所有鄰節點的節點,乙個unvisited列表用於存放還未遍歷過其所有鄰節點的節點。我們會不斷地進行迭代運算,直到unvisited列表為空,即所有的節點都已經訪問過(遍歷過其所有鄰節點)。

顯然初始狀態,visited列表為空,unvisited列表中包含所有的節點[a,b,c,d,e]。

然後我們需要乙個列表用於記錄所有節點到a節點,起始節點之間的最短距離,以及最短路徑中該節點之前的節點。

第一步,初始化這個** :

顯然a到a的距離為0,其餘節點到a的距離為未知,初始化為正無窮。

節點節點到a的距離

最短路徑中該節點之前的節點a0

b∞\infin

∞c∞

\infin

∞d∞

\infin

∞e∞

\infin

∞那麼每一次迭代,我們需要做的,就是在unvisited列表中,選擇乙個到a距離最短的節點,並遍歷更新其所有unvisited列表中的鄰節點。

例如第一次迭代中,unvisited未訪問列表中a節點到a的最短距離最短,那麼我們首先就訪問a所有unvisited的節點 b 和 d。簡單來說,如果通過a訪問b比起之前的方式要距離更短,那麼我們就更新b到初始點的距離為新的最短距離,並將b之前的節點更新為a。那麼在這個例子中,通過a訪問b的距離為6,通過a訪問d的距離為1,顯然距離都比正無窮要小,則更新列表如下 :

節點節點到a的距離

最短路徑中該節點之前的節點a0

b6ac

\infin

∞d1ae∞

\infin

∞同時更新visited列表以及unvisited列表:

visited : [a]

unvisited : [b,c,d,e]

既然未訪問列表仍然不為空,我們繼續迭代,選擇d作為新的訪問節點,因為節點d目前到a的距離最短。那麼節點d在unvisited列表中的鄰節點有 b e,那麼我們更新b,e的值和其原來的距離進行對比。 b : 1+2 = 3 < 6 \space

e : 1+1 = 2 < ∞

\infin

∞。更新列表如下 :

節點節點到a的距離

最短路徑中該節點之前的節點a0

b1+2 = 3dc

\infin

∞d1a

e1+1 = 2

d同時更新visited列表以及unvisited列表:

visited : [a,d]

unvisited : [b,c,e]

我們繼續迭代,方法同上。

訪問e節點,更新列表 :

節點節點到a的距離

最短路徑中該節點之前的節點a0

b1+2 = 3dc

1+1+5 = 7ed

1ae1+1 = 2

d同時更新visited列表以及unvisited列表:

visited : [a,d,e]

unvisited : [b,c]

繼續訪問b,更新列表 :

b的唯一沒有訪問的鄰節點為c,但a> … >b>c 的距離為 3+5=8 >7,因此c到節點a的距離不變。

節點節點到a的距離

最短路徑中該節點之前的節點a0

b1+2 = 3dc

1+1+5 = 7ed

1ae1+1 = 2

d同時更新visited列表以及unvisited列表:

visited : [a,d,e,b]

unvisited : [c]

最後我們訪問c,列表不變,因為c的所有鄰節點都已經訪問過了。

最終的結果如下 :

節點節點到a的距離

最短路徑中該節點之前的節點a0

b3dc

7ed1

ae2d

通過迪傑斯特拉演算法,我們可以完備地遍歷所有有權圖中的節點,並在最後返回乙個所有節點到初始點的最短距離,以及對應的最短路徑的所有節點之前的節點。之後通過不斷訪問最短路徑中該節點之前的節點,我們就可以很簡單地還原出最短路徑。例如對節點c而言,c之前的節點為e,e之前的節點為d,d之前的節點為a,因此最短路徑還原為a > d > e > c。

參考 :

[1] graph data structure 4. dijkstra』s shortest path algorithm

[2] (熟肉)dijkstra演算法詳解,輕鬆入門——youtube

Dijkstra(迪傑斯特拉)演算法

迪傑斯特拉 dijkstra 演算法是典型最短路徑演算法,用於計算乙個節點到其他節點的最短路徑。它的主要特點是以起始點為中心向外層層擴充套件 廣度優先搜尋思想 直到擴充套件到終點為止。指定乙個節點,例如我們要計算 a 到其他節點的最短路徑 引入兩個集合 s u s集合包含已求出的最短路徑的點 以及相...

dijkstra迪傑斯特拉演算法

注意 1.標頭檔案climits的int max,加上2整數會溢位,每次相加前得判斷被加值是否為int max,int max 10為負數 2.得先初始化再對d s c s g,cost等賦值 fill d 0 d 0 max,int max fill g 0 0 g 0 0 max max,int...

迪傑斯特拉 Dijkstra 演算法

迪傑斯特拉 dijkstra 演算法是典型最短路徑演算法,用於計算乙個節點到其他節點的最短路徑。它的主要特點是以起始點為中心向外層層擴充套件 廣度優先搜尋思想 直到擴充套件到終點為止。通過dijkstra計算圖g中的最短路徑時,需要指定起點s 即從頂點s開始計算 dijkstra演算法算是貪心思想實...