最優子結構——最短路徑的子路徑也是最短路徑,動態規劃和貪心演算法的乙個重要指標。
環路
一條最短路徑不可能包含環路
1) 環路權重為負,如果有一條環路權重為負,則不存在最短路徑
2) 環路權重為零,如果包含該環路,則將該環路去掉即可
3) 環路權重為正,去掉改環路可以得到更短的路徑,因此不可能是最短路徑
最短路徑的表示
對於每個結點v,維持乙個前驅結點v.p,可能是另外乙個結點或者nil
鬆弛操作
對每個結點,維持乙個屬性v.d,記錄從源結點s到結點v的最短路徑權重的上界;稱v.d為s到v的最短路徑估計。
initialize-single-source(g, s)//最短路徑估計及前驅結點初始化
for each vertex v 屬於 g.v
v.d = inf
v.p = nil
s.d = 0
鬆弛過程【針對一條邊(u, v)】:先測試是否可以對s到v的最短路徑進行改善,測試的方法為,將從結點s到結點u的最短路徑距離加上u與v之間的邊權重,並與當前的s到v的最短路徑估計進行比較;如果前者更小,則進行v.d和v.p的更新
relax(u, v, w)
if v.d > u.d + w(u, v)
v.d = u.d + w(u, v)
v.p = u
bellman-ford演算法
一般情況下的單源最短路徑問題,邊的權重可以為負值
返回乙個布林值,以表明是否存在乙個從源結點可以到達的權重為負值的環路
bellman-ford(g, w, s)
initialize-single-source(g, s)//對各個結點的p和d進行初始化
for i = 1 to |g.v| - 1//每乙個點,對每一條邊都需要進行鬆弛操作
for each edge(u, v) 屬於 g.e
relax(u, v, w)
for each edge(u, v) 屬於 g.e
if v.d > u.d + w(u, v)//如果不存在權重為負值的環路,則二者是相等的
return false
return true
有向無環圖中的單源最短路徑問題
根據結點的拓撲順序次序來對帶權重的有向無環圖g = (v, e)進行邊的鬆弛操作,可以在o(v + e)時間內計算出從單源最短路徑問題
dag-shortest-paths(g, w, s)
topologically sort the vertices of g//先對點進行拓撲排序,o(v + e)
initialize-single-source(g, s)
for each vertex u, taken in topologically sorted order
//按拓撲排序對結點進行一遍處理
for each vertex v 屬於 g.adj[u]
relax(u, v, w)
dijkstra演算法
要求所有變的權重都為非負值
維持了一組結點集合s,源結點s到這組結點的最短路徑已經求出;演算法重複從v-s中選擇最短路徑估計最小的結點u,將u加入到集合s中,然後對所有從u發出的邊進行鬆弛
使用乙個最小優先佇列q儲存結點集合s,每個結點的關鍵字為其d值
dijkstra(g, w, s)
initialize-single-source(g, s)
s = 空集
q = g.v
while q 不等於 空集
u = extract-min(q)
//第乙個被提取的點即源結點
s = s 並上
for each vertex v 屬於 g.adj[u]
relax(u, v, w)
單源最短路徑
include define max 999 define maxverts 10 typedef struct graph void chushi graph g void dij graph int key,int int int main for i 1 i g.numverts i dij ...
單源最短路徑
單源最短路徑問題,即在圖中求出給定頂點到其他任一頂點的最短路徑。1.最短路徑的最優子結構性質 該性質描述為 如果p i,j 是從頂點i到j的最短路徑,k和s是這條路徑上的乙個中間頂點,那麼p k,s 必定是從k到s的最短路徑。證明 假設p i,j 是從頂點i到j的最短路徑,則有p i,j p i,k...
單源最短路徑
在最短路徑問題中,給定乙個帶權重的有向圖g v,e 和權重函式w e r,該權重函式將每條邊對映到實數值的權重上。圖中一條路徑p v0,v1,vk 的權重w p 是構成該路徑的所有邊的權重之和。定義從結點u到結點v的最短路徑權重 u,v 從結點u到結點v的最短路徑則定義為任何一條權重w p u,v ...