贝尔曼-福德算法

我在上一篇博客中讲解了狄克斯特拉算法,该算法可以用于寻找权值都为正的有向无环图的最短路径,我也提到了如果碰到权值为负的情况可以使用贝尔曼-福德算法,那么今天就让我们学习一下贝尔曼-福德算法是如何处理负权值和环路的。

其实理解了狄克斯特拉算法之后理解贝尔曼-福德算法就很容易了,如果说狄克斯特拉算法是用一种“广度”的方式,每次寻找源点所能到达的距离最短的一个点,更新其邻居节点的距离。那么贝尔曼-福德算法就是用一种“深度”的方式,每次找到所有的路径,进行“松弛”操作最终找到最短路径。贝尔曼-福德算法每次对所有的边进行松弛,每次松弛都会得到一条最短路径,所以总共需要要做的松弛操作是V - 1次。在完成这么多次松弛后如果还是可以松弛的话,那么就意味着,其中包含负环。相比狄克斯特拉算法其时间复杂度较高,达到O(V*E),V代表顶点数,E代表边数。

你可能不了解什么是松弛操作,其实就是不断寻找距离更短的路径:

假设有这样的一个图

从原点出发经由一条路径直达A的路径为M,直达B的路径为N,存在从A到B的路径L,如果你找到M+L<N的路径了,那么就是做了一次松弛操作

那么为什么说要做V-1次松弛操作呢?

考虑无环图的极限情况,所有节点排成一条线,那么最远的路段是V-1

那么遇到有环图呢?

最长路径便成了无限,但没经过一次环至少增加两短路,我们只要经过V-1次松弛便可以检测出来是否有环,对于有环的图我们还要对其性质进行判断,如果是正权值的环那么就排除改路径,如果是负权值的环那么此题就无法求解,因为走环的次数越多权值和越小。

如果你了解狄克斯特拉算法的话写这个也很容易,我们同样需要三个表一个距离表一个父节点表一个全部节点表,然后就是遍历V-1次,并判断是否存在环

我们找一个图 起始的样子是这样的

我们得到了一张从Start开始,第一步只能到达A、B两点的初始化的距离表,也就是说,此时到达A、B的距离是已知的,因为可以由Start直接到达; 得到一个只有Start点作为父节点的两个点A、B的父地点表;还有一个全部路径的路径图。

我们遍历路径表中的 相邻两点之间的全部路径 一次,根据距离表更新每个点的到达距离。也就是对图进行一次松弛操作:

我们可以看到,初始化

  • 7
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幽蓝丶流月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值