算法导论-----图论-----Bellman-ford 算法
Bellman-ford 算法
1.运行bellman算法后可返回一个布尔值,表明图中是否存在一个从原点可达的负权回路,若存在,无解;不存在,返回最短路径及权值
2.此法运用松弛技术不断减少从源点s到v的最短路径权的估计值d[v],直至达到最短路径实际的值σ(s,v),算法返回true当且仅当不包含从原点可达的负权回路
BELLMAN-FORD(G,w,s)
INITIALIZE-SINGLE-SOURCE(G,s)
For i=1 to |V[G]|-1
Do for each edge(u,v)属于E[G]
Do relax(u,v,w)
For each edge(u,v)属于E[G]
Do if d[v]>d[u]+w(u,v)
Then return false
Return true
3.为什么松弛|V|-1次能得到正确答案?(假设无负环)
P=<v0,v1,…,vk>是任一条从s到v的最短无环路径,s=v0,vk=v。路径p至多有|V|-1条边
所以k<=|V|-1,for循环松弛了|E|的所有边,第i次迭代被松弛的边为(vi-1,vi),由路径松弛性质可知d[v]=d[vk]=σ(s,vk)=σ(s,v)
4. 设m为所有每对顶点u,v中边数最小值中的最大值,则可在松弛m+1次以后终止(注意要求无负环,要么while不会停止)(课后习题24.1-3)
RELAX-M(u, v,w)
if d[v] > d[u] + w(u, v)
then d[v] ← d[u] + w(u, v)
π[v] ← u
changes ← TRUE
BELLMAN-FORD-(M+1) (G,w, s)
INITIALIZE-SINGLE-SOURCE(G, s)
changes ← TRUE
while changes = TRUE
do changes ← FALSE
for each edge (u, v) ∈ E[G]
do RELAX-M(u, v,w)
5.若从原点s到v的某些路径中存在负权回路则置d[v]=负无穷(课后习题24.1-4)
Bellman-Ford-New(G, w, s)
Initialize-Single-Source(G, s)
for i ← 1 to |V[G]| - 1
do for each edge (u,v) 属于E[G]
do Relax[u, v, w]
for each edge (u, v) 属于E[G]
do if d[v] > d[u] + w(u, v)
d[v] = 负无穷
for each v such that d[v] =负无穷
do Follow-And-Mark-Pred(v)
Follow-And-Mark-Pred(v)
if p[v] != nil and d[p[v]] != 负无穷
do d[p[v]] =负无穷
Follow-And-Mark-Pred(p[v])
else
return