求单源最短路径的算法(Bellman-Ford)

本文主要讲解求单源最短路径的BellmanFord算法。

BellmanFord算法

BellmanFord算法能够在一般情况下,解决单源最短路径问题。允许图中出现权为负数的边。该算法还会返回一个布尔值。如果布尔值为false,表示途中存在从源点可达的权为负的回路。

首先介绍一下松弛计算。如下图:

 

<?xml:namespace prefix = v ns = “urn:schemas-microsoft-com:vml” /><?xml:namespace prefix = o ns = “urn:schemas-microsoft-com:office:office” />

《求单源最短路径的算法(Bellman-Ford)》

松弛计算之前,点B的值是8,但是点A的值加上边上的权重2,得到5,比点B的值(8)小,所以,点B的值减小为5。这个过程的意义是,找到了一条通向B点更短的路线,且该路线是先经过点A,然后通过权重为2的边,到达点B

当然,如果 出现一下情况

 

《求单源最短路径的算法(Bellman-Ford)》

则不会修改点B的值,因为34>6

 

BellmanFord算法可以大致分为三个部分

第一,初始化所有点。每一个点保存一个值,表示从原点到达这个点的距离,将原点的值设为0,其它的点的值设为无穷大(表示不可达)。

第二,进行循环,循环下标为从1n1n等于图中点的个数)。在循环内部,遍历所有的边,进行松弛计算。

第三,遍历途中所有的边(edgeuv)),判断是否存在这样情况:

dv > d (u) + w(u,v)

则返回false,表示途中存在从源点可达的权为负的回路。

 

之所以需要第三部分的原因,是因为,如果存在从源点可达的权为负的回路。则 应为无法收敛而导致不能求出最短路径。

考虑如下的图:

 

《求单源最短路径的算法(Bellman-Ford)》

经过第一次遍历后,点B的值变为5,点C的值变为8,这时,注意权重为-10的边,这条边的存在,导致点A的值变为-2。(8 10=-2

 

 

《求单源最短路径的算法(Bellman-Ford)》

第二次遍历后,点B的值变为3,点C变为6,点A变为-4。正是因为有一条负边在回路中,导致每次遍历后,各个点的值不断变小。

 

在回过来看一下bellmanford算法的第三部分,遍历所有边,检查是否存在dv > d (u) + w(u,v)。因为第二部分循环的次数是定长的,所以如果存在无法收敛的情况,则肯定能够在第三部分中检查出来。比如

 

《求单源最短路径的算法(Bellman-Ford)》

此时,点A的值为-2,点B的值为5,边AB的权重为55 > -2 + 5. 检查出来这条边没有收敛。

 

所以,BellmanFord算法可以解决图中有权为负数的边的单源最短路径问。

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/lokibalder/article/details/3430974
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞