【数据结构-图】3.图的最短路径的几种算法(图解+演绎)
最短路徑
最短路徑的求取有兩種經(jīng)典的算法,分別是Dijkstra算法和Floyd算法
這Dijkstra算法的算法思想是基于貪心算法的,也就是選擇權(quán)值最小的邊
而Floyd算法的算法思想是根據(jù)動(dòng)態(tài)規(guī)劃,不斷迭代取得的
Dijkstra算法:從頂點(diǎn)出發(fā),優(yōu)先選擇與連接兩個(gè)頂點(diǎn)集合中的權(quán)值最小的邊,求單源最短路徑
Floyd算法:求多源最短路徑,不斷迭代列表中的數(shù)據(jù)
Dijkstra
Dijkstra算法的核心是實(shí)時(shí)更新三個(gè)列表信息構(gòu)成的 —— 這與最小生成樹中的Prim算法相似
第一個(gè)列表visited,是判斷是否已選訪問過改點(diǎn),若為true,表示頂點(diǎn)已被訪問,若為false,表示頂點(diǎn)未被訪問,初始為false;
第二個(gè)列表minDist,表示兩個(gè)點(diǎn)之間的距離,初始為∞(無窮大);
第三個(gè)列表parent,存放它的雙親結(jié)點(diǎn),初始為-1
圖示過程
有如下圖,共有5個(gè)頂點(diǎn),10條邊,邊的權(quán)值如下
首先選擇頂點(diǎn)1,更新visited,頂點(diǎn)1的visited的值為T(Add)。
與此同時(shí),與頂點(diǎn)1相連接的頂點(diǎn)分別為頂點(diǎn)2和頂點(diǎn)5,邊權(quán)分別為10和5。因?yàn)?0和5均小于inf(Update),所以更新minDist列表中頂點(diǎn)2和頂點(diǎn)5兩個(gè)部分,同時(shí)需要將頂點(diǎn)2和頂點(diǎn)5的parent列表更新為1(Scan)如下圖
由于權(quán)邊5<10,頂點(diǎn)5的列表visited的值為F,所以更新visited,使頂點(diǎn)5的visited的值為T(Add)。
與此同時(shí),與頂點(diǎn)1、頂點(diǎn)5相連接的頂點(diǎn)分別為頂點(diǎn)2、頂點(diǎn)3和頂點(diǎn)4,邊權(quán)分別為10,3,9,2。因?yàn)?和2均小于inf,權(quán)值3小于權(quán)值10(Update),所以更新minDist列表中頂點(diǎn)2、頂點(diǎn)3和頂點(diǎn)4三個(gè)部分,同時(shí)需要將頂點(diǎn)2、頂點(diǎn)3和頂點(diǎn)4的parent列表更新為5(Scan)
由于權(quán)邊在標(biāo)綠色的權(quán)邊,2最小,頂點(diǎn)4的列表visited的值為F,所以更新visited,使頂點(diǎn)4的visited的值為T(Add)。
與此同時(shí),與頂點(diǎn)1、頂點(diǎn)5和頂點(diǎn)4相連接的頂點(diǎn)分別為頂點(diǎn)2、頂點(diǎn)3,邊權(quán)分別為10,3,9,6,7。此時(shí)權(quán)值最短路徑即為當(dāng)前最短,不需要更新(Update),在最短路徑不需要更新的情況下,parent列表也不需要更新(Scan)如下圖
由于權(quán)邊在標(biāo)綠色的權(quán)邊,3最小,頂點(diǎn)2的列表visited的值為F,所以更新visited,使頂點(diǎn)2的visited的值為T(Add)。
與此同時(shí),與頂點(diǎn)1、頂點(diǎn)5、頂點(diǎn)4和頂點(diǎn)2相連接的頂點(diǎn)為頂點(diǎn)3,邊權(quán)分別為10,9,6,1。此時(shí)權(quán)值最短路徑即為當(dāng)前最短,不需要更新(Update),在最短路徑不需要更新的情況下,parent列表也不需要更新(Scan)如下圖
由于權(quán)邊在標(biāo)綠色的權(quán)邊,1最小,頂點(diǎn)3的列表visited的值為F,所以更新visited,使頂點(diǎn)3的visited的值為T(Add)。
與此同時(shí),所有頂點(diǎn)相連接,由于權(quán)值1<權(quán)值9(Update),所以更新minDist列表中頂點(diǎn)3這個(gè)部分,同時(shí)需要將頂點(diǎn)3的parent列表更新為2(Scan)如下圖
Floyd
Floyd算法的基本思想是:遞推產(chǎn)生兩個(gè)n階方陣序列,一個(gè)方陣D是: D(?1),D(A),D(B),D(C),…,D(n)D^{(-1)}, D^{(A)},D^{(B)},D^{(C)}, \dots,D^{(n)}D(?1),D(A),D(B),D(C),…,D(n),其中 D(n)[i][j]D^{(n)}[i][j]D(n)[i][j] 用以記錄從頂點(diǎn) viv_ivi? 到頂點(diǎn) vjv_jvj? 的路徑長(zhǎng)度,n表示操行結(jié)點(diǎn)n的運(yùn)算步驟;另一個(gè)方陣S是 S(?1),S(A),S(B),S(C),…,S(n)S^{(-1)}, S^{(A)},S^{(B)},S^{(C)}, \dots,S^{(n)}S(?1),S(A),S(B),S(C),…,S(n),其中 S(n)[i][j]S^{(n)}[i][j]S(n)[i][j] 用以記錄從頂點(diǎn) viv_ivi? 到頂點(diǎn) vjv_jvj? 的路徑上的下一個(gè)點(diǎn),n表示操行結(jié)點(diǎn)n的運(yùn)算步驟。
初始情況,若兩個(gè)頂點(diǎn)之間存在邊,在方陣D記錄邊的權(quán)值,若不存在直接聯(lián)系,就記錄為inf;方陣S記錄路徑上的下一個(gè)點(diǎn),初始狀態(tài)就是該點(diǎn)本身。
解釋:D(A)[i][j]D^{(A)}[i][j]D(A)[i][j] 表示從頂點(diǎn) viv_ivi? 到頂點(diǎn) vjv_jvj?必經(jīng)過結(jié)點(diǎn)A
存在一個(gè)圖由3個(gè)頂點(diǎn)和5條有向邊組成,初始狀況下的方陣D和方陣S如下:
由圖可知
從A到B,從A到C都可以直接到達(dá);
從B到A可以直接到達(dá),從B到A到C的權(quán)值和 BA+AC=10+13=23BA+AC=10+13=23BA+AC=10+13=23 大于4,所以不更新;
從C到A可以直接到達(dá),從C到A到,此時(shí)權(quán)值為 CA+AB=5+6=11CA+AB=5+6=11CA+AB=5+6=11,因?yàn)?11<inf11<inf11<inf,所以更新方陣D橫軸為C縱軸為B這個(gè)方格中的數(shù)據(jù),inf→11inf→11inf→11
與此同時(shí),需要更改方陣S橫軸為C縱軸為B這個(gè)方格中的數(shù)據(jù),B→A
由圖可知
從A到B可以直接到達(dá)和從A到B到C的權(quán)值和為 AB+BC=6+4=10AB+BC=6+4=10AB+BC=6+4=10 小于13,所以更新方陣D橫軸為A縱軸為C這個(gè)方格中的數(shù)據(jù),13→1013→1013→10 ;
與此同時(shí),需要更改方陣S橫軸為A縱軸為C這個(gè)方格中的數(shù)據(jù),C→B
從B到A,從B到C均可以直接到達(dá),所以不更新;
從C到B到A,此時(shí)權(quán)值為 inf+BA=infinf+BA=infinf+BA=inf,因?yàn)?5<inf5<inf5<inf,所以不更新;從C到B不直達(dá),所以 11<inf11<inf11<inf,所以不更新
由圖可知
從A到C到B的權(quán)值和為 AC+CB=13+inf=infAC+CB=13+inf=infAC+CB=13+inf=inf 大于于6,所以不需要更新;從A到C可以直接到達(dá),不需要更新
與此同時(shí),需要更改方陣S橫軸為A縱軸為C這個(gè)方格中的數(shù)據(jù),C→B
從B到C到A的權(quán)值和為 BC+CA=4+5=9BC+CA=4+5=9BC+CA=4+5=9 小于10,需要更改方陣D橫軸為B縱軸為 A1個(gè)方格中的數(shù)據(jù),10→910→910→9,從B到C均可以直接到達(dá),所以不更新;
與此同時(shí),需要更改方陣S橫軸為B縱軸為A這個(gè)方格中的數(shù)據(jù),A→C
從C到A可以直接到達(dá),不需要更新;從C到B不直達(dá),所以 11<inf11<inf11<inf,所以不更新
總結(jié)
以上是生活随笔為你收集整理的【数据结构-图】3.图的最短路径的几种算法(图解+演绎)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【数据结构-图】2.多图详解最小生成树(
- 下一篇: 【数据结构-图】4.拓扑排序和关键路径(