版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1第10
章
單源最短路徑單源最短路徑問題簡介
2Dijkstra算法
3Ballman-Ford算法 1421.單源最短路徑問題簡介問題定義:在給定的加權(quán)有向圖G(V,E)中,取一頂點s為源點,計算從源點s到其他每個點v的最短路徑p(s,v),v
V,以及它的加權(quán)長度。最短路徑的長度記為
(s,v)。主要算法:
Dijkstra算法和Ballman-Ford算法都采用貪心法策略,包括初始化和循環(huán)部分。初始化置d(v)
=
,v
V–{s},置d(s)
=0。d(v)含義是,到目前為止,能找到的從s到v的路徑中最短的一條長度。循環(huán)部分,每一輪都會有至少一個新頂點的最短路徑被確定下來。這樣,在n輪之后,所有頂點的最短距離就產(chǎn)生了。(有些學者把Ballman-Ford算法歸為動態(tài)規(guī)劃。)32.Dijkstra算法Dijkstra算法要求圖G(V,E)中邊的權(quán)值是非負實數(shù)。Dijkstra算法與Prim算法幾乎完全一樣。Dijkstra算法構(gòu)造一棵最短路徑樹T,而Prim算法是構(gòu)造MST。Dijkstra算法既適用于有向圖又適用于無向圖。Dijkstra算法簡介
分為兩部分,初始化部分和循環(huán)部分。(1)初始化部分(和Prim算法完全一樣,但d(v)的含義不同):foreachv
V
d(v)
(v)
nil //點v的父親
endford(s)
0這里,d(v)表示從源點s到v的暫時距離,即目前找到的最短距離。在Prim算法中,d(v)表示的是,點v與當前已形成的樹T的最短距離。4Dijkstra算法簡介(繼續(xù)1)(2) 循環(huán)部分:循環(huán)前,樹T是空集。以d(v)為關(guān)鍵字,用優(yōu)先隊列Q把所有樹外的頂點組織起來。一共循環(huán)n次,每次循環(huán)做兩件事:(2,1)
找出當前樹T以外的頂點中有最小d(u)的頂點u。
和Prim算法完全一樣,如果
(u)=h,那么,Dijkstra算法把邊
(h,u)加到樹T中,并且把u從Q中刪除,修復(fù)Q。因為d(s)=0
<
,循環(huán)第一輪必定選取源點s。因為
(s)=nil,第一輪只把點s加到T里,沒有邊加入T。(2,2)
逐個檢查點u的還在樹外的每個鄰居v,即v
Adj(u),v
Q。點u成了樹中的點,為鄰居v提供一條新路徑,長為d(u)+w(u,v)。如果d(u)+w(u,v)<d(v),則d(v)更新為d(v)
d(u)+w(u,v)。(偽碼見下頁)5Dijkstra算法簡介(繼續(xù)2)foreachv
Adj(u)
ifv
Q
and
d(u)+w(u,v)<d(v)
then
d(v)
d(u)+w(u,v)
(v)
u
endifendfor這一部分的偽碼幾乎和Prim相同。只要作如下改動就變成Prim算法了。把d(u)
+w(u,v)<d(v)
改為
w(u,v)<d(v),和把d(v)
d(u)
+w(u,v) 改為
d(v)
w(u,v),也就是把”
d(u)
+“去掉,
就變成Prim算法了。
(完整的Dijkstra算法的偽碼見下頁)6SSSP-Dijkstra(G(V,E),s) //SSSP–SingleSourceShortestPath1 for
eachv
V2 d(v)
3
(v)
nil4 endford(s)
06 V(A)
//A是樹T的邊集合,V(A)是與A中邊關(guān)聯(lián)的頂點集合7 A
//初始,樹T的邊集合為空8 Q
V
//所有樹外的頂點組織為Q9 while
Q
10 u
Extract-Min(Q) //從Q中剝離最小d(u),修復(fù)Q11 A
A
{(
(u),u)} //如
(u)=nil,A不變12 V(A)
V(A)
{u}13 foreachv
Adj(u)14
if
v
Q
andd(u)+w(u,v)<d(v)
15
then
d(v)
d(u)+w(u,v)16
(v)
u17
endif
endforendwhile18 returnT(V(A),A)
//最短路徑樹19 End把14行和15行中的d(u)+去掉就變成Prim算法了。7例10.1
用Dijkstra算法找出下圖中以頂點s為源點的最短路徑樹。1243852abscde131085解:d(a)=
(a)=nild(c)=
(c)=nil1243852abscde131085d(b)=
(b)=nild(d)=
(d)=nild(e)=
(e)=nild(s)=0
(s)=nil(a)初始化,源點是頂點ss1243852abcde131085d(a)=12
(a)=sd(c)=
(c)=nild(b)=4
(b)=sd(d)=
(d)=nild(e)=
(e)=nild(s)=0
(s)=nil(b)頂點
s被選中,更新頂點a,b8d(a)=9
(a)=bd(c)=14
(c)=b1243852abscde131085d(b)=4
(b)=sd(d)=12
(d)=bd(e)=
(e)=nild(s)=0
(s)=nil(c)頂點b被選中,更新頂點a,c,ds1243852abcde131085d(a)=9
(a)=bd(c)=12
(c)=a
d(b)=4
(b)=sd(d)=12
(d)=bd(e)=
(e)=nild(s)=0
(s)=nil(d)頂點a被選中,更新頂點cd(a)=9
(a)=bd(c)=12
(c)=a1243852abscde131085d(b)=4
(b)=sd(d)=12
(d)=bd(e)=17
(e)=cd(s)=0
(s)=nil(e)頂點c被選中,更新頂點es1243852abcde131085d(a)=9
(a)=bd(c)=12
(c)=a
d(b)=4
(b)=sd(d)=12
(d)=bd(e)=14
(e)=dd(s)=0
(s)=nil(f)頂點d被選中,更新頂點e9d(a)=9
(a)=bd(c)=12
(c)=a1243852abscde131085d(b)=4
(b)=sd(d)=12
(d)=bd(e)=14
(e)=dd(s)=0
(s)=nil(g)頂點e被選中,不需更新頂點s4382abcde5d(a)=12
(a)=sd(c)=12
(c)=a
d(b)=4
(b)=sd(d)=12
(d)=bd(e)=14
(e)=dd(s)=0
(s)=nil(h)Dijkstra
算法產(chǎn)生的最短路徑樹10Dijkstra算法正確性證明假設(shè)源點s有路徑到達圖中每一個點。顯然算法一定輸出一棵樹。只需證明以下命題:初始化后,每一輪while循環(huán)中,點u被選中并連到樹T上去時,從s到u的路徑就是最短路徑,其長是d(u)=
(s,u)。我們用歸納法證明。歸納基礎(chǔ):因為d(s)=0<
,第一個被選中的點必定是源點s。因為圖中所有權(quán)值都大于等于零,顯然d(s)=
(s,s)=0正確。歸納步驟:假沒k次循環(huán)后,算法已正確地選取了k個頂點(1
k
n-1),使得樹中從s到這k個頂點的任一個點z的路徑就是圖G中從s到z的一條最短路徑,長為d(z)=
(s,z)?,F(xiàn)在證明算法選取的第k+1個頂點u也是正確的。(接下頁)11歸納步驟(繼續(xù)1)設(shè)
(u)=h,則有d(u)=d(h)
+w(h,u)。由歸納假設(shè),d(h)是從源點s到點
h的路徑長度,并且有d(h)=
(s,h)。所以,d(u)就是沿著樹中從源點s到點h,再到點u的路徑的長度。當我們把邊(h,u)加到樹中,d(u)就是樹中從源點s到點u的路徑的長度。所以,我們只需證明,這條路徑是圖G中從s到u的最短路徑。我們用反證法,并為此假設(shè)圖中有一條比d(u)還短的路徑p(s,u),w(p(s,u))<d(u)。我們將由此導(dǎo)出矛盾。我們?yōu)轫旤c集合V定義一個割,C={S,V-S},其中S是當前已選入樹T中的k個點,而V-S是樹外的n-k個點,包括點u。因為源點s和頂點u分屬割的兩邊,路徑p(s,u)含有至少一條交叉邊。設(shè)(x,y)是路徑p(s,u)上第一條交叉邊,x
S,y
V-S。如下圖(10.2)所示,我們可以把路徑p(s,u)分為三段:(接下頁)12第1段p1,w(p1)=d(x)第2段p2,w(p2)=w(x,y)第3段p3,是從y到u的一
條路徑,w(p3)
0sxySp1p3d(y)
d(u)
d(y)V–Su割C=(S,V-S)w(x,y)p2因為w(p1)+w(p2)=d(x)+w(x,y)正是在先前x被選中時用于更新d(y)的,所以必有d(y)
d(x)+w(x,y)。否則,d(y)在那個時刻應(yīng)該更新而沒有更新,違反了算法。所以,我們必有如下關(guān)系: d(y)
w(p1)+
w(p2)
w(p(s,u))<d(u),即d(y)
<d(u)。這與算法矛盾,因為算法在選取點u時,必有d(u)
d(y)。所以,d(u)是圖中從s到u的最短路徑長度,歸納成功。
d(x)
歸納步驟(繼續(xù)2)13Dijkstra算法的復(fù)雜度顯然與Prim算法的復(fù)雜度相同,總結(jié)如下:用數(shù)組作為Q來存儲d(v),v
V,復(fù)雜度為O(n2)。用最小堆作為Q來存儲d(v),v
V,復(fù)雜度為O(mlgn)。用裴波拉契堆作為Q來存儲d(v),v
V,復(fù)雜度為O(nlgn
+m)。14Bellman-Ford
算法簡介由三部分組成,分述如下。初始化: 與Dijkstra算法的初始化完全相同,組織為一個子程序如下:Initialize-Single-Source(G(V,E),s)foreachv
V
d(v)
(v)
nilendford(s)
0End3.Bellman-Ford算法15Bellman-Ford
算法簡介
(繼續(xù)1)循環(huán)部分: 做n-1輪循環(huán)。每輪只做一件事,即對每條邊(u,v)進行一次松弛(relax)操作如下:Relax(u,v)if
d(u)+w(u,v)<d(v)
then
d(v)
d(u)+w(u,v)
(v)
uendifEnd其實,這就是Dilkstra算法的更新操作。不同的是,Dilkstra算法每一輪只對u的鄰居
v
Adj(u)進行更新。而Bellman-Ford算法對每條邊都要進行松弛操作。所以,我們稱一輪循環(huán)為一輪松弛遍歷,遍歷時,邊的順序可任意,只要每條邊都被松弛操作即可。16Bellman-Ford
算法簡介
(繼續(xù)2)檢查部分。在循環(huán)部分完成后,需要檢測有沒有源點可達的負回路。檢測很簡單,就是再做一次松馳遍歷。在遍歷中,如果有某頂點v的d(v)得到更新,變得更小,則說明有源點可達負回路。這時,算法報告有負回路,并取消所有計算。反之,任何d(v)都沒有更新,算法成功結(jié)束。這時,每個d(v)即是從源點s到頂點v的最短路徑的距離,其對應(yīng)的最短路徑則可以通過父親指針而找到。(偽碼見下頁)17Bellman-Ford
(G(V,E),s)Initialize-Single-Source(G(V,E),s) //初始化for
i
1to
n-1 //n=|V|,松弛遍歷 foreachedge(u,v)
E Relax(u,v) endforendforforeachedge(u,v)
E //開始檢測負回路 if
d(u)
+w(u,v)<d(v)
thenreturn
false //有源點可達負回路
endifendforA
{(
(v),v)|v≠s,v
V} //最短路徑樹中邊的集合constructT(V,A) //構(gòu)造最短路徑樹return
(T(V,A)),End18例:
用Bellman-Ford算法找出下圖中以頂點s為源點的最短路徑樹。
-2acebd-1-57486s5-3解:d(b)=
(b)=nild(s)=0
(s)=nilacebd-2-1-57486s5-3(a)初始狀態(tài),源點是頂點sd(a)=
(a)=nild(e)=
(e)=nild(d)=
(d)=nild(c)=
(c)=nild(s)=0
(s)=nilacebd-2-1-57486s5-3(b)第1輪松馳遍歷后狀態(tài)。遍歷順序為(a,b),(b,e),(b,d),(s,a),(s,c),(c,a),(c,b),(c,d),(d,e)。d(a)=1
(a)=cd(b)=3
(b)=cd(e)=12
(e)=dd(d)=5
(d)=cd(c)=-3
(c)=s19(c)第2輪松馳遍歷后狀態(tài)。遍歷順序為(s,a),(s,c),(c,b),(c,d),(d,e),(c,a),(b,d),(b,e),(a,b)。acebd-2-1-57486s5-3d(a)=1
(a)=cd(b)=-1
(b)=ad(e)=2
(e)=bd(d)=-2
(d)=bd(c)=-3
(c)=sd(s)=0
(s)=nilacebd-2-1-57486s5-3(d)第3輪松馳遍歷后狀態(tài)。遍歷順序為(s,a),(s,c),(c,b),(c,d),(d,e),(c,a),(b,d),(b,e),(a,b)。d(b)=-1
(b)=ad(e)=-2
(e)=bd(d)=-6
(d)=bd(c)=-3
(c)=sd(s)=0
(s)=nild(a)=1
(a)=c20(e)第4輪松馳遍歷后狀態(tài)。遍歷順序為(s,a),(s,c),(c,b),(c,d),(d,e),(c,a),(b,d),(b,e),(a,b)。acebd-2-1-57486s5-3d(a)=1
(a)=cd(b)=-1
(b)=ad(e)=-2
(e)=bd(d)=-6
(d)=bd(c)=-3
(c)=sd(s)=0
(s)=nilacebd-2-1-57486s5-3(f)第5輪松馳遍歷后狀態(tài)。遍歷順序為
(s,a),(s,c),(c,b),(c,d),(d,e),(c,a),(b,d),(b,e),(a,b)。d(b)=-1
(b)=ad(e)=-2
(e)=bd(d)=-6
(d)=bd(c)=-3
(c)=sd(s)=0
(s)=nild(a)=1
(a)=cacebd-2-1-54s-3(g)Bellman-Ford算法產(chǎn)生的最短路徑樹d(a)=1
(a)=cd(b)=-1
(b)=ad(c)=-3
(c)=sd(s)=0
(s)=nild(d)=-6
(d)=bd(e)=-2
(e)=b21Bellman-Ford算法正確性證明正確性證明包括兩部分。第一部分證明在圖G(V,E)不含源點可達負回路的情況下,Bellman-Ford算法正確地算出各頂點的最短路徑。第二部分證明在G(V,E)含有源點可達負回路的情況下,Bellman-Ford算法正確地檢測出負回路并報告。我們通過兩個定理來證明。注意,只有所有邊的權(quán)值都非負時,Bellman-Ford算法才能用于無向圖。這是因為,如果把一條無向邊(u,v)換成一對有向邊(u,v)和(v,u)的話,它們形成兩條邊的負回路。22Bellman-Ford算法正確性證明(繼續(xù)1)從源點s到頂點v的最短路徑可能不止一條,其中必有一條路徑p(s,v),它不僅有最短的加權(quán)距離,w(p(s,v))=
(s,v),而且,它的不加權(quán)距離,即它含有的邊的個數(shù),|p(s,v)|,在所有最短路徑中也最小。定義10.1設(shè)v
V是有向圖G(V,E)中一頂點,從源點s到頂點v的最小最短距離定義如下: D(s,v)=min{|p(s,v)||滿足w(p(s,v))=
(s,v)的路徑p(s,v)}。滿足|p(s,v)|=D(s,v)和w(p(s,v))=
(s,v)的路徑p(s,v)稱為從s到v的最小最短路徑。由定義10.1,如果D(s,v)=k,那么,源點s到頂點v的所有加權(quán)的最短路徑中,有一條含有k條邊,而其余的加權(quán)的最短路徑至少含有k條邊或者更多。顯然,最小最短距離不會超過n-1,D(s,v)
n-1。(接下頁)23Bellman-Ford算法正確性證明(繼續(xù)2)定理10.1如果G(V,E)不含s可達的負回路,那么在算法進行了n-1輪松弛遍歷后,圖G中從源點s到頂點v的最短距離是d(v),即
(s,v)=d(v)。(假定從s到v有通路,否則d(v)=
。)證明:我們先有以下兩點觀察:因為沒有負回路,s到v的所有最短路徑中必有一條簡單路徑。因為d(v)值只減不增,一旦有d(v)=
(s,v),d(v)便不會再變。我們用歸納法證明下面的命題。我們對變量k進行歸納證明。命題:如果D(s,v)=k,那么在k輪松弛遍歷后,d(v)=
(s,v)。歸納基礎(chǔ):當k=0時,源點s的距離d(s)=0。因為沒有負回路,
(s,s)=d(s)=0。從s到s路徑不含邊,D(s,s)=0,所以命題正確。(接下頁)24Bellman-Ford算法正確性證明(繼續(xù)3)定理10.1證明,命題證明(繼續(xù))歸納步驟:假設(shè)在k-1輪松弛遍歷后(k
1),命題成立。也就是,任何點v
(v
V),如果D(s,v)
k-1,那么從s到v的最短距離有等式d(v)=
(s,v)。我們證明在第
k輪松弛遍歷后,命題也成立。假設(shè)D(s,v)=k,從s到v的最短路徑是p(s,v)=<s,v1,v2,…,vk-1,v>,w(p(s,v))=
(s,v)。我們斷言,它的子路徑p(s,vk-1)=<s,v1,v2,…,vk-1>一定是s到vk-1的最短路徑,即
(s,vk-1)=w(p(s,vk-1))。這是因為,否則的話,s到vk-1有權(quán)值更小的路徑p*
(s,vk-1)。那么沿著p*
(s,vk-1),從s到vk-1后,再到v就是一條比w(p(s,v))權(quán)值更小的從s到v的路徑。這與w(p(s,v))=
(s,v)矛盾。(接下頁)25Bellman-Ford算法正確性證明(繼續(xù)4)定理10.1證明,命題證明(繼續(xù)1)因為p(s,vk-1)有k-1條邊,又是最短路徑,所以
D(s,vk-1)
k-1。那么,根據(jù)歸納假設(shè),必有d(vk-1)=
(s,vk-1)=w(p(s,vk-1))。所以,當?shù)趉輪松弛遍歷對邊(vk-1,v)進行松弛操作時,如果此時有d(v)>d(vk-1)+w(vk-1,v),則必定被更新為:d(v)=d(vk-1)+w(vk-1,v)=w(p(s,vk-1))+w(vk-1,v)=w(p(s,v))=
(s,v),
(v)=vk-1。歸納成功。否則,d(v)
d(vk-1)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 廣東科學技術(shù)職業(yè)學院《中學政治學科教學法與微格實訓(xùn)》2023-2024學年第一學期期末試卷
- 廣東金融學院《體育場館智能化運營》2023-2024學年第一學期期末試卷
- 廣東工業(yè)大學《路面工程》2023-2024學年第一學期期末試卷
- 廣東工程職業(yè)技術(shù)學院《NoSQL數(shù)據(jù)庫系統(tǒng)》2023-2024學年第一學期期末試卷
- 廣東創(chuàng)新科技職業(yè)學院《園林設(shè)計初步Ⅱ》2023-2024學年第一學期期末試卷
- 廣東財經(jīng)大學《醫(yī)學課程》2023-2024學年第一學期期末試卷
- 小學生計算能力提升課件
- 廣東財經(jīng)大學《高級通信系統(tǒng)》2023-2024學年第一學期期末試卷
- 廣東白云學院《素描人體》2023-2024學年第一學期期末試卷
- 贛州職業(yè)技術(shù)學院《餐飲運營管理1(菜肴酒水)》2023-2024學年第一學期期末試卷
- 2024年南京市第一醫(yī)院分院高層次衛(wèi)技人才招聘筆試歷年參考題庫頻考點附帶答案
- 鄧州市龍理鄉(xiāng)第一初級中學-2025年春節(jié)寒假跨學科主題實踐作業(yè)模板【課件】
- 電力改造電力安裝施工合同
- (新疆一模)2025屆高三高考適應(yīng)性檢測分學科第一次模擬考試 生物試卷(含答案解析)
- 【大學課件】文物數(shù)字化技術(shù)及數(shù)字化文物系統(tǒng)初探
- 高一數(shù)學上學期期末模擬試卷03-【中職專用】2024-2025學年高一數(shù)學上學期(高教版2023基礎(chǔ)模塊)(解析版)
- 2024年中央經(jīng)濟工作會議精神解讀
- 熱電站汽輪機發(fā)電安全操作規(guī)程(2篇)
- 2025年中考物理復(fù)習資料專題18 生活用電(知識梳理+典例+練習)(原卷版)
- 2024衛(wèi)星遙感應(yīng)用服務(wù)平臺建設(shè)與運營合同
- 2023-2024學年廣東省深圳市福田區(qū)八年級(上)期末歷史試卷
評論
0/150
提交評論