• 沒有找到結果。

路徑規劃的方法

第七章 最短路徑規劃

7.2.1 Bellman-Ford 演算法

說明演算法之前,我們必須假設一個網路圖,然後針對網路圖上的節點,運用此 一演算法求出最短路徑,藉以瞭解演算法的實際推演過程。所以我們假設有一網路圖 如圖 7.1 所示,其內共有 5 個網路節點,且節點 A 為目的點,並假設每一節點至少存 在一條路徑可到達目的點,由圖可知若每個節點最多只能經過一次,則從任一節點 i 到目的節點 A,最多包含有 h 個路段(h≦4;h=4 表經過所有節點後才到達節點 A),現 在我們就來解決從所有節點到節點 A 的最短路徑問題:

7 2

4 3 1 3 3

圖 7.1 五節點網路範例圖 7.2.1.1 參數定義:

1、令d 表節點 i 到節點 j 的路徑長度,若ij dij =∞表節點 i 到節點 j,沒有直接相連 的路徑。

2、令D 表節點 i 到節點 A(目的節點),所經過路段數目少於 h 個路段的最短路徑長ih 度。

7.2.1.2 演算法說明:

1、設定初值:

(1) 由網路圖得知所有的節點 i 到節點 j 之路徑長度,以d 表之。 ij

(2) 令Di0 =∞ 對所有的 i≠A。

B D

C E

A

(3) 令DAh =0 對所有的 h。

2、對所有的 h≧0,以下列公式計算Dih+1 之最小值

Dih+1 =m in j[dij+Dhj Dih]對所有的 i≠A。

3、重複步驟 2,直至對所有的 i 均有 = ih+1 h

i D

D 之結果時則停止。

這個演算法首先找到一條路徑(One-arc)可到達的最短路徑,再找到兩條路徑 (Two-arc)可到達的最短路徑,如此一直找下去直到對所有的 i 均有Dih =Dih+1之結 果,或 h≧N-l(N 表所有節點數 )時停止。

7.2.1.3 範例說明:

我們運用圖 7.1 的網路圖以說明演算法的推演過程 : 1、設定初值:

DA0 = D1A =D2A =...=0 DB0 = DC0 = DD0 =...=∞

dBA =2;dCA =3;dBC =4;dDB =7;dEC =3;dDE =1;dED =3 dBD =dBE =dCB =dCD =dCE =dDC =dEB =∞(由網路圖得知)

2、求一條路徑(One-arc)可到達的最短路徑(h=1): D1A =0 (初值)

D1B =m in [dBA +D0AdBC+DC0dBD +DD0dBE +DE0DB0]

=m in

[

2+04+++

]

=2

DC1 =m in [dCA +D0AdCB +DB0dCD +DD0dCE +DE0DC0] =m in

[

3+0+++

]

=3

D1D =m in [dDA +D0AdDB +DB0dDC +DC0dDE +DE0DD0] =m in

[

+07++1+

]

=

D1E =m in [dEA +D0AdEB +DB0dEC +DC0dED +DD0DE0]

=m in

[

+0+3+3+

]

=

3、求兩條路徑(Two-arc)可到達的最短路徑(h=2): DA2 =0 (初值)

DB2 =m in [dBA +D1AdBC+D1CdBD +D1DdBE +D1ED1B] =m in

[

2+04+3++2

]

=2

DC2 =m in [dCA +D1AdCB +D1BdCD +D1DdCE +D1EDC1]

=m in

[

3+0+2++3

]

=3

DD2 =m in [dDA +D1AdDB +D1BdDC +DC1dDE +D1ED1D] =m in

[

+07+2+31+

]

=9

DE2 =m in [dEA +D1AdEB +D1BdEC +DC1dED +D1DD1E]

=m in

[

+0+23+33+

]

=6

4、求三條路徑(Three-arc)可到達的最短路徑(h=3): DA3 =0 (初值)

DB3 =m in [dBA +DA2dBC+DC2dBD +DD2dBE +DE2DB2] =m in

[

2+04+3+9+62

]

=2

DC3 =m in [dCA +D2AdCB +DB2dCD +DD2dCE +DE2DC2]

=m in

[

3+0+2+9+63

]

=3

DD3 =m in [dDA +D2AdDB +DB2dDC +DC2dDE +DE2DD2]

=m in

[

+07+2+31+69

]

=7

DE3 =m in [dEA +D2AdEB +DB2dEC +DC2dED +DD2DE2]

=m in

[

+0+23+33+96

]

=6

5、下來求四條路徑(Four-arc)可到達的最短路徑(h=4),我們得到對所有節點都有

4 3

i

i D

D = 的結果 ,故演算法結束,各節點到節點 A 的最短路徑值即為D 的值 ,i4 演算法示意圖如圖 7.2 所示:

D1B =2 D1D =∞ DB2 =2 DD2 =9 2 2 7

D1A =0 3 DA2 =0 3

DC1 =3 D1E =∞ DC2 =3 DE2 =6 One-arc Two-arc

DB3 =2 DD3 =7 DB4 =2 DD4 =7 2 2

1 1 DA3 =0 3 3 DA4 =0 3 3

DC3 =3 DE3 =6 DC4 =3 DE4 =6

Three-arc Four-arc 圖 7.2 Bellman-Ford 演算法示意圖

B

A

C

D

E

A

B D

C E

B D

C E

A A

B D

C E

7.2.2 Dijkstra's 演算法

Dijkstra's 演算法的概念,是以目前最近的節點向外擴張,即將目前所剩節點 中,選出最短距離者加以擴張,每擴張一個節點,就比較「目前所剩節點到達目的節 點的距離」與「由此節點經過擴張節點再到達目的節點的距離」,取其最短者。所以 此演算法是以一個階段一個階段,漸漸增加路徑長度的方式,來求其最短路徑。現在 我們就來探討此一演算法,解決從所有節點到節點 A 的最短路徑的方式。

7.2.2.1 參數定義:

1、所有路徑長度都不為負值,且目的節點為 A。

2、N 表網路上所有節點數。

3、S 為一陣列,用以放置已處理完畢的節點。

4、T 為一陣列,用以放置尚未處理之節點 (與 S 互為補數 ) 5、D 及i D 表節點 i 或節點 j,到目的節點 A 的最短路徑。 j

6、d 表節點 i 到節點 j 的路徑長度,若 i=j 則ij d =0。若節點 i 到節點 j,沒有 ij

直接相連的路徑,則dij =∞。 7.2.2.2 演算法說明:

1、設定初值:

(1) 由網路圖得知所有的節點 i 至節點 j 之路徑長度,以d 表之。 ij (2) 令 S={A},T=N-S。

(3) 令DA =0。

(4) 令Dj =djA對所有的 j≠A。

2、在 T 中尋找下一個最近節點,並將此節點移至 S 內 Di =m in jT[D ]對所有的j iT

3.、T 不為空集合,則針對 T 內節點進行路徑長度修正,公式如下:

對所有的 jTDj =m in jT[Dj dji +Di]。

4、重複步驟 2、3,直至 T 為空集合(或 S=N)為止。

7.2.2.3 範例說明:

我們仍然運用圖 7.1 的網路圖,來說明 Dijkstra's 演算法的推演過程:

1、設定初值:

N={A,B,C,D,E}

S={A} //A 為目的節點

T={B,C,D,E} //此為尚未處理的節點的集合

=0

DA ;D B =dBA =2;DC =dCA =3;DD =dDA =∞;DE =dEA =∞ 2、在 T 中找出距離 A 最近的節點 ,因D ,B D ,C D ,D D 中E D 為最小 , B 故選擇 B 節點

Di =m in jT[D ],j iT

=min{D ,B D ,C D ,D D }=min{2,3,∞,∞}=2 E 所以 i=B,將 B 節點移至 S 內

⇒S={A,B};T={C,D,E}

3、T 不為空集合,則針對 T 內節點進行路徑長度修正 公式:對所有的 jTDj =m in jT[Djdji +Di] ⇒ DC =m in

[

DCdCB +DB

]

=m in

[

3+2

]

=3

DD =m in

[

DDdDB +DB

]

=m in

[

7+2

]

=9

DE =m in

[

DEdEB +DB

]

=m in

[

+2

]

=

4、在 T 中找出距離 A 最近的節點 ,因D ,C D ,D D 中E D 為最小 ,故 C 選擇 C 節點

Di =m in jT[D ],j iT

=min{D ,C D ,D D }= min{3,9,∞}=3 E 所以 i=C,將 C 節點移至 S 內

⇒ S={ A,B,C };T={ D,E }

5、T 不為空集合,則針對 T 內節點進行路徑長度修正 公式:對所有的 jTDj =m in jT[Dj dji +Di]

DD =m in

[

DDdDC +DC

]

=m in

[

9+3

]

=9

DE =m in

[

DEdEC +DC

]

=m in

[

3+3

]

=6

6、在 T 中找出距離 A 最近的節點,因D ,D D 中E D 為最小,故選擇 E 節點 E

T j

Di =m in [D ],j iT

=min{D ,D D }= min{9,6}=6 E 所以 i=E,將 E 節點移至 S 內 ⇒ S={ A,B,C,E };T={ D }

7、T 仍不為空集合,則針對 T 內節點進行路徑長度修正 公式:對所有的 jTDj =m in jT[Djdji +Di]

DD =m in

[

DDdDE +DE

]

=m in

[

9 1+6

]

=7

8、因 T 中只剩 D 節點(D 的值最小),所以只能選擇 D 節點 D Di =m in jT[D ],j iT = min{D }= min{7}=7 D

所以 i=D,將 D 節點移至 S 內 ⇒ S={A,B,C,E,D};T={}

9、T 為空集合則結束,此時D 內的值即為最短路徑值,其演算法示意圖如圖 i 7.3 所示。

DB =2 DD =∞ DB =2 DD =9 2 2 7

DA =0 DA =0

3 3

DC =3 DE =∞ DC =3 DE =∞

i = B i = C DB =2 DD =9 DB =2 DD =7 2 2

1 DA =0 3 3 DA =0 3 3

DC =3 DE =6 DC =3 DE =6

i = E i = D 圖例說明:目前計算路徑 最短路徑

圖 7.3 Dijkstra’s 演算法示意圖 7.2.3 Floyd's 演算法

Floyd's 演算法是計算所有點到所有點的最短路徑,其基本想法是認為:「如果 k 點是 i 到 j 上最佳路徑的一點,則 i 到 k 及 k 到 j 之路徑,均為最佳路徑」。所以其 路徑的求得係以「前一次 i 點到 j 點間的距離

(

Dk1

[ ]

ij

)

」與「前一次由 i 點經過 k 點到 j 點的距離

(

Dk1

[ ]

i,k +Dk1

[ ]

kj

)

相比較,取其較小者。故有下列 Floyd's 方程式:

B

A

C

D

E

A

B D

C E

B D

C E

A A

B D

C E

Dk

[ ]

ij =m in

(

Dk1

[ ]

ijDk1

[ ]

ik +Dk1

[ ]

kj

)

演算法步驟:

procedure Floyd((L[1..n,1..n]) array D[l..n,1..n]

D← L //D 儲存各點至其他各點之最短路徑值 for k← l to n do

for i← l to n do for j← l to n do

D[i,j] ← min(D[i,j],D[i,k] + D[k,j]) return