文轉:http://blog.csdn.net/zxq2574043697/article/details/9451887
一:
最短路徑算法
1. 迪傑斯特拉算法
2. 弗洛伊德算法
二:
1.
迪傑斯特拉算法
求
從源點到其余各點的最短路徑
依
最短路徑的長度遞增
的次序求得各條
路徑
路徑長度最短
的最短路徑的特點:
在這條路徑上,
必定只含一條弧
,並且這條
弧的
權值最小。
下一條
路徑長度次短
的最短路徑的特點:
它只可能有兩種情況:或是
直接從源點到該
點
(
只含一條弧
)
;
或者是
從源點經過頂點
v
1
,再到達該頂點
(
由兩條弧組成
)
。
再下一條
路徑長度次短
的最短路徑的特點
:
它可能有三種情況:或者是
直接從源點到該
點
(
只含一條弧
)
;
或者是
從源點經過頂點
v
1
,再到達該頂點
(
由兩條弧組成
)
;或者是
從源點經過頂點
v
2
,再到達該頂點。
其余最短路徑的特點:
它或者是
直接從源點到該點
(
只含一條弧
)
;
或者是
從源點經過已求得最短路徑的頂點,
再到達該頂點
。
迪傑斯特拉算法
算法:
(a)
初始化:
用起點v到該頂點w的直接邊(弧)初始化最短路徑,否則設為∞;
(b)
從未求得最短路徑的終點中選擇路徑長度最小的終點u:即求得v到u的最短路徑;
(c)
修改最短路徑:
計算u的鄰接點的最短路徑,若(v,…,u)+(u,w)<(v,…,w),則以(v,…,u,w)代替。
(d)
重復
(b)-(c)
,直到求得v到其余所有頂點的最短路徑。
特點:總是按照從小到大的順序求得最短路徑。
頂點
A
到其他頂點的最短路徑


Dijkstra
算法可描述如下:
¶
初始化:
S
←
{
v
0
};
dist
[
j
]
←
Edge
[0][
j
],
j
= 1, 2, …,
n
-
1;
//
n為圖中頂點個數
·
求出最短路徑的長度:
dist
[
k
]
←
min{
dist
[
i
] },
i
Î
V
-
S
;
S
←
S
U
{
k
};
¸
修改:
dist
[
i
]
←
min{
dist
[
i
],
dist
[
k
] +
Edge
[
k
][
i
] },
對於每一個
i
Î
V
-
S
;
¹
判斷: 若S = V, 則算法結束,否則轉
二:
弗洛伊德算法
求每對頂點之間的最短路徑。
依次計算矩陣A(0),A(1),…,A(n)。
A
(0)
為鄰接矩陣,
計算A(k)時,
A (k) (i,j)=min{A (k-1) (i,j), A (k-1) (i,k)+A (k-1) (k,j)} 。
A (k) (i,j)=min{A (k-1) (i,j), A (k-1) (i,k)+A (k-1) (k,j)} 。
A(0) [i][j]是從頂點vi 到vj , 中間頂點是v0的最短路徑的長度, A(k) [i][j]是從頂點vi 到vj , 中間頂點的序號不大於k的最短路徑的長度, A(n-1)[i][j]是從頂點vi 到vj 的最短路徑長度。
弗洛伊德算法的基本思想是:
從
v
i
到
v
j
的所有可能存在的路徑中,選出
一條長度最短的路徑
。
n
次試探
:
若
<v
i
,v
j
>
存在,則存在路徑
{v
i
,v
j
}
//
路徑中不含其它頂點
若
<v
i
,v
0
>,<v
0
,v
j
>
存在,則存在路徑
{v
i
,v
0
,v
j
}
//
路徑中所含頂點序號不大於0
若
{v
i
,…,v
1
}, {v
1
,…,v
j
}
存在,
則存在一條路徑
{v
i
, …, v
1
, …v
j
}
//
路徑中所含頂點序號不大於1
…
依次類推,則
vi
至
vj
的最短路徑應是上述
這些路徑中,路徑長度最小者。
求每對頂點之間的最短路徑




弗洛伊德算法
技巧:計算A(k)的技巧。
第
k
行、第
k
列、對角線的元素保持不變,
對其
余元素,考查
A(i,j)
與
A(i,k)+A(k,j)
(第k列i“行”元素加上第k行j“列”元素,簡記為“行+列”),如果后者更小則替換A(i,j),同時修改路徑。

本節給出的求解最短路徑的算法不僅適用於帶權有向圖,對帶權無向圖也可以適用。因為帶權無向圖可以看作是有往返二重邊的有向圖,只要在頂點vi 與vj 之間存在無向邊(vi , vj ),就可以看成是在這兩個頂點之間存在權值相同的兩條有向邊< vi , vj >和< vj , vi >。
試利用Dijkstra算法求下圖中從頂點1到其他各頂點間的最短路徑,寫出執行算法過程中各步的狀態
