Bellman-Ford算法

Bellman-Ford是另一种单源最短路径算法,他的功能和 Dijkstra算法一样。但是运行速度比 Dijkstra慢。时间复杂度为O(V*E)

因为 Dijkstra对加权有向图里面的负环路不能正常工作。但是Bellman-Ford可以正常工作。

下面介绍Bellman-Ford的工作流程

procedure BellmanFord(list vertices, list edges, vertex source)
   // This implementation takes in a graph, represented as lists of vertices and edges,
   // and fills two arrays (distance and predecessor) with shortest-path information

   // Step 1: initialize graph初始化有向图和Dijkstra一样。
   for each vertex v in vertices:
       if v is source then distance[v] := 0
       else distance[v] := infinity
       predecessor[v] := null

   // Step 2: relax edges repeatedly重复进行relax操作,
   for i from 1 to size(vertices)-1:
       for each edge (u, v) with weight w in edges:
           if distance[u] + w < distance[v]:
               distance[v] := distance[u] + w
               predecessor[v] := u

   // Step 3: check for negative-weight cycles检测负环路。
   for each edge (u, v) with weight w in edges:
       if distance[u] + w < distance[v]:
           error "Graph contains a negative-weight cycle"
下面证明该算法的正确性:

正确性可以用归纳法证明。

引理. 经过I次重复:

  • 如果距离u不是无穷大,那么他等于一些路径从源点到u的长度;
  • 如果存在一条路径从源点到u拥有i条边,那么距离u最多为从s到u的最短路径经过最多i条边;
    证明. 对于推理的基本情况, 考虑i=0并且在循环被执行第一次之前。那么对于源点,源点的距离是0,这是对的,对于其他的点u,u点的距离是无穷大,也是对的,因为没有从源点到u经过了0条边。
    对于归纳情况,我们首先证明第一部分。考虑档点的距离被更新为距离v:=距离u + uv边的权重。更具归纳假设距离u是从源点到u的一条路径的长度。那么距离u+uv边的权重是是一条从源点到u再到v的路径的长度。

    对于第二部分,考虑从源点到u包含最多i条边的最短长度。那么该最短路径的一部分从源点到v点会有最多i-1条边。根据归纳推理,距离v是经过i-1轮循环式这条路径的最大长度。然而uv边的权重+距离v是从s到u的最大长度。在第i轮循环距离u和uv边的权重+距离v比较,然后如果uv边的权重+ 距离v 更小 ,距离u将被设置。所以经过i轮循环距离u最多为从s到u的最短路径包括最多i条边。

    如果没有负环路,那么所有的最短路径经过每个点最多一次,所以在第三步不需要更多的证明。
    相反情况,对于任何环路经过v0 。。。。。v【k - 1】
    v[i]<=v[(i - 1) mod k].distance + v[i]<=v[(i - 1) mod k]v[i].weight.
原文地址:https://www.cnblogs.com/xiaokangzi/p/3576149.html