大黑书《离散数学及其应用》之Dijkstra算法
一、引言
????????引言部分為概述性內容,可以跳過(寫這部分的原因主要是避免CSDN發文助手的不聰明檢測)。在本部分中,我將介紹最短路徑算法、Dijkstra算法、Floyd算法。
????????最短路徑算法。最短路徑算法主要分為兩種,一種是單源最短路徑算法,另一種是多源最短路徑算法。在單源最短路徑算法中,是在給定一個帶權連通圖(且權重為正數)下,求某一個頂點到其他所有頂點的最短路徑長度。而在多源最短路徑算法中,也是在給定一個帶權連通圖下,求圖中任意頂點到其他所有頂點的最短路徑長度。
????????Dijkstra算法。Dijkstra算法是由荷蘭計算機科學家狄克斯特拉(Dijkstra)于1959 年提出的,因此又叫狄克斯特拉算法。是從一個頂點到其余各頂點的最短路徑算法,解決的是有向圖中最短路徑問題。 其基本原理是:每次新擴展一個距離最短的點,更新與其相鄰的點的距離。當所有邊權都為正時,由于不會存在一個距離更短的沒擴展過的點,所以這個點的距離永遠不會再被改變,因而保證了算法的正確性。不過根據這個原理,用Dijkstra求最短路的圖不能有負權邊,因為擴展到負權邊的時候會產生更短的距離,有可能就破壞了已經更新的點距離不會改變的性質。來源:MBA智庫百科。
????????Floyd算法。Floyd算法是一種利用動態規劃的思想尋找給定的加權圖中多源點之間最短路徑的算法,與Dijkstra算法類似。該算法名稱以創始人之一、1978年圖靈獎獲得者、斯坦福大學計算機科學系教授羅伯特·弗洛伊德命名。在Floyd算法中,邊權可正可負。來源:百度百科。
二、Dijkstra算法
????????在《離散數學及其應用》中,Dijkstra算法如下
? ? ? ? 在該算法中,S是一個集合,書中說表示一個特殊頂點集(按照我的理解是,當源點a到某個頂點v的最短路徑長度確定時,v就被加入這個集合中);L(v)是源點a到頂點v的最短路徑長度。
? ? ? ? 算法的輸入為一個帶權連通圖,即頂點集、帶權鄰接矩陣w和源點a。
? ? ? ? 在初始化階段:L(v)被賦予無窮大,L(a)被賦予0;S被賦予空集。
? ? ? ? 在算法的核心步驟中(從while z?S開始到最后),算法主要更新L(v)的值和S。
? ? ? ? 而算法的輸出是L(z),即包含了a到各頂點的最短路徑長度的一個列表。
三、示例
????????單看算法是很難理解這個算法的,我就結合自己的理解給這個算法做一個簡單的示例吧。
? ? ? ? 1、問題描述
????????如下圖所示的帶權圖中,頂點a與頂點z之間的最短通路的長度是多少?
? ? ? ? 2、問題求解(巨詳細版)
????????現在我們就根據上面的Dijkstra算法對上述問題進行求解。求解步驟分別為:算法輸入、初始化、核心步驟求解和輸出。
? ? ? ? ①算法輸入
? ? ? ? G = <V,E>,權重映射w。其中,
????????V = {a,b,c,d,e,z};// 節點集
????????E = {(a,b),(a,d),(d,e),(b,e),(b,c),(c,z),(e,z)};// 邊集
????????權重映射w:對于存在的邊,w(a,b) = 4,w(a,d) = 2,w(d,e) = 3,w(b,e) = 3,w(b,c) = 3,w (c,z) =2,w(e,z) = 1;對于不存在的邊(i,j)(i,j∈V),w(i,j) = ∞。
? ? ? ? ②算法初始化
? ? ? ? L(a)=∞,L(b)=∞,L(c)=∞,L(d)=∞,L(e)=∞,L(z)=∞;// L存儲a到各頂點的最短路徑
????????L(a)=0;
? ? ? ? S=?;
? ? ? ? ③算法核心步驟求解過程 (建議自己在草稿紙上畫一個圖結合看)
? ? ? ? 當頂點z?S時,執行以下步驟。
? ? ? ? 第一輪(S=?,z?S,執行):
? ? ? ? (1) L(a)=0,L(b)=∞,L(c)=∞,L(d)=∞,L(e)=∞,L(z)=∞,S=? // L(a)最小且a?S,選擇節點a;
? ? ? ? (2) 把a加入S,S={a};
? ? ? ? (3) 所有不屬于S={a}的頂點有:b、c、d、e、z
? ? ? ? ? ? ? ? b:L(a)+w(a,b)=0+4=4,比L(b)=∞更小,更新L(b)=4;
? ? ? ? ? ? ? ? c:L(a)+w(a,c)=0+∞=∞,不比L(c)=∞更小,不更新L(c);
? ? ? ? ? ? ? ? d:L(a)+w(a,d)=0+2=2,比L(d)=∞更小,更新L(d)=2;
? ? ? ? ? ? ? ? e:L(a)+w(a,e)=0+∞=∞,不比L(e)=∞更小,不更新L(e);
? ? ? ? ? ? ? ? z:L(a)+w(a,z)=0+∞=∞,不必L(z)=∞更小,不更新L(z);
? ? ? ? 根據上面的更新,L(a)=0,L(b)=4,L(c)=∞,L(d)=2,L(e)=∞,L(z)=∞。
? ? ? ? 第二輪(S={a},z?S,執行):
? ? ? ? (1) L(a)=0,L(b)=4,L(c)=∞,L(d)=2,L(e)=∞,L(z)=∞,S={a} // L(d)最小且d?S,選擇節點d;
? ? ? ? (2) 把d加入S,S={a,d};
? ? ? ? (3) 所有不屬于S={a,d}的頂點有:b、c、e、z
? ? ? ? ? ? ? ? b:L(d)+w(d,b)=2+∞=∞,不比L(b)=4更小,不更新L(b);
? ? ? ? ? ? ? ? c:L(d)+w(d,c)=2+∞=∞,不比L(c)=∞更小,不更新L(c);
? ? ? ? ? ? ? ? e:L(d)+w(d,e)=2+3=5,比L(e)=∞更小,更新L(e)=5;
? ? ? ? ? ? ? ? z:L(d)+w(d,z)=2+∞=∞,不比L(z)=∞更小,不更新L(z);
????????根據上面的更新,L(a)=0,L(b)=4,L(c)=∞,L(d)=2,L(e)=5,L(z)=∞。
? ? ? ? 第三輪(S={a,d},z?S,執行):
? ? ? ? (1) L(a)=0,L(b)=4,L(c)=∞,L(d)=2,L(e)=5,L(z)=∞,S={a,d} // L(b)最小且b?S,選擇節點b;
? ? ? ? (2) 把b加入S,S={a,d,b};
? ? ? ? (3) 所有不屬于S={a,d,b}的頂點有:c、e、z
? ? ? ? ? ? ? ? c:L(b)+w(b,c)=4+3=7,比L(c)=∞更小,更新L(c)=7;
? ? ? ? ? ? ? ? e:L(b)+w(b,e)=4+3=7,不比L(e)=5更小,不更新L(e);
? ? ? ? ? ? ? ? z:L(b)+w(b,z)=4+∞=∞,不比L(z)=∞更小,不更新L(z);
????????根據上面的更新,L(a)=0,L(b)=4,L(c)=7,L(d)=2,L(e)=5,L(z)=∞。
? ? ? ? 第四輪(S={a,d,b},z?S,執行):
? ? ? ? (1) L(a)=0,L(b)=4,L(c)=7,L(d)=2,L(e)=5,L(z)=∞,S={a,d,b} // L(e)最小且e?S,選擇節點e;
? ? ? ? (2) 把e加入S,S={a,d,b,e};
? ? ? ? (3) 所有不屬于S={a,d,b,e}的頂點有:c、z
? ? ? ? ? ? ? ? c:L(e)+w(e,c)=5+∞=∞,不比L(c)=7更小,不更新L(c);
? ? ? ? ? ? ? ? z:L(e)+w(e,z)=5+1=6,比L(z)=∞更小,更新L(z)=6;
????????根據上面的更新,L(a)=0,L(b)=4,L(c)=7,L(d)=2,L(e)=5,L(z)=6。
? ? ? ? 第五輪(S={a,d,b,e},z?S,執行):
? ? ? ? (1) L(a)=0,L(b)=4,L(c)=7,L(d)=2,L(e)=5,L(z)=6,S={a,d,b} // L(z)最小且z?S,選擇節點z;
? ? ? ? (2) 把z加入S,S={a,d,b,e,z};
? ? ? ? (3) 所有不屬于S={a,d,b,e,z}的頂點有:c
? ? ? ? ? ? ? ? c:L(z)+w(z,c)=6+2=8,不比L(c)=7更小,不更新L(c);
????????根據上面的更新(實際上沒有更新),L(a)=0,L(b)=4,L(c)=7,L(d)=2,L(e)=5,L(z)=6。
? ? ? ? 第六輪(S={a,d,b,e,z},z∈S,不執行,跳出循環)
? ? ? ? ④算法輸出
? ? ? ? 算法輸出是L(z)=6,即頂點a到頂點z的最短路徑長度。
? ? ? ? 3、問題求解(簡潔版)
? ? ? ? 貼一下圖,免得大家翻頁太麻煩。
? ? ? ? 求解過程如下:其中紅色箭頭表示了S和L的變化與更新。
? ? ? ? 4、練習題:求a到z的最短路徑長度。
? ? ? ? 答案:13.
四、個人思考
????????1、從上面給出的算法中,Dijkstra算法只能找到a到其他頂點的最短路徑長度,而無法找到源點a到其他頂點的最短路徑。如果要找到路徑,我覺得要考慮更加復雜的變量在其中。
????????2、從上面給出的算法中,Dijkstra算法并沒有求源點a到其他所有頂點的最短路徑長度,而是求到z就算法終止了。其中示例中所求到的最短路徑長度包括a到S中的任意一個頂點,而不包括c。按照我的理解,當算法的循環條件設為while |S|!=|V|的時候,我覺得可以求a到其他所有頂點的最短路徑長度。
????????3、Dijkstra算法是動態規劃類型的算法嗎?是,因為L(v)的更新條件是
? ? ? ? 具有動態規劃中的最優子結構。
五、參考
????????1、離散數學及其應用,Kenneth H. Rosen,機械工業出版社;
????????2、百度百科;
????????3、智庫百科;
????????4、知乎博文:Dijkstra算法。
總結
以上是生活随笔為你收集整理的大黑书《离散数学及其应用》之Dijkstra算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 开源优秀 Library
- 下一篇: 列的数目比列的名字要多_你们要的甘特图来