【经典算法】最短路径算法——Bellman-Ford

🌈 个人主页:十二月的猫-CSDN博客
🔥 系列专栏: 🏀算法启示录

💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 

目录

前言

松弛视角

伪代码展示

三角形理论 

 松弛操作可行性证明

 Bellman-Ford算法

算法思想

1.流程描述

2.流程图解

3.流程阐释

算法伪代码

算法证明 

路径松弛性质

最短路径证明

总结


前言

最短路径算法是图论中一类重要算法,其功能就如名字一样——求解点与点之间最短距离。

首先,先让我们对最短路径算法有一个概观,看看都有哪些种类的最短路径算法,每一个种类中代表的算法又是什么。

单源最短路径算法:从一个起点出发求解其到其他所有其他点的最短距离

多源最短路径算法:从所有点出发求解其到其他所有其他点的最短距离 

松弛视角

关键点:

1、松弛和动态规划都是解决最短路径的方法。

2、松弛的本质就是对图固有属性三角理论的修正。

3、松弛和动态规划方法存在一定的重合,有时可以相互转化。两者并未有固定的优秀等次之分。

4、一些算法采用松弛视角解决,另一些采用动态规划视角来解决

伪代码展示

最短路径的求解包含两个步骤:一、初始化操作;二、松弛操作

松弛是最短路径求解过程中最好用的手段之一

两个操作的伪代码如下:

初始化操作:

INITIALIZE(G,s)
    for each vertex v ∈ G.V
        v.d=∞
        v.π=NULL
    s.d=0

松弛操作:

RELAX(u,v,w)
    if v.d>u.d+w(u,v)
        v.d=u.d+w(u,v)
        v.π=u

松弛操作的本质是对三角形理论的修正 

三角形理论 

定义:

对于任何边(u,v)∈E,都有d(s,v)<=d(s,u)+w(u,v)

d(s,v)表示s到v的最短路径

任何图都满足三角形理论,三角形理论是图形的固有性质

 松弛操作可行性证明

既然三角形理论是任何图形的固有性质。那么一旦一个图形中的出发源点s到目的点v的距离不符合三角形理论,那么就说明d(s,v)是不准确的(偏大),或者d(s,u)是不准确的(偏小)。显然我们初始化时令d(s,v)都是正无穷,所以d(s,u)偏小是不可能的。因此必然是d(s,v)偏大,需要修正。此时我们就令v.d=u.d+w(u,v),从而完成对d(s,v)的修正。

如果顶点v到s的距离满足三角形理论,那么此时的距离可能是正确的(即最短距离)。如果顶点v到s的距离经过所有其他顶点的三角形理论检验仍然满足,则说明此时得到的一定是正确的(即一定是最短距离)。

一次次的修正(松弛),点与点之间距离不断减少,直到最后得到最短路径。这就是松弛操作求解最短路径的可行性证明

较难理解!!但是希望大家可以好好看一遍

 Bellman-Ford算法

贝尔曼福特算法是一个一般性的单源最短路径算法。一般性意味着它适用于存在负权重但无负权重回路的情况。相比较于贝尔曼福特算法,运行效率更高的迪杰斯特拉算法是一个相对特殊的算法,只能用于只有正权重的图求解单源最短路径。

当然,可以这么说,贝尔曼福特算法是一种动态规划算法,迪杰斯特拉算法是一种贪婪算法。

算法思想

1.流程描述

Bellman-Ford 算法对图中的每一条边进行松弛,并且这个松弛要进行V-1轮

2.流程图解

让我们拿《算法导论》中的示例图走一遍,带大家体会算法的流程

先明确以下两个点:

1、 每一个图表示每一轮松弛后的结果。即:a是原始图,b是进行第一轮松弛后的结果,c是进行第二轮松弛后的结果。总共有5个点,所以松弛了4轮。

2、阴影的线段表示:无论每一轮松弛边的内部顺序如何,进行一轮松弛后至少会达到的结果(这一句话希望大家好好体会~~)

举个b图的例子,让大家感受一下这个流程 :

对b图:从a图中随机选择一条边(t,x),进行松弛x结果仍然不变;从a图中再随机选择(x,t)边,进行松弛,由于两者都是正无穷,所以t的结果也不变;从a图中随机选择(s,t),进行松弛得到结果:t为6;从a图中随机选择(y,z)边,进行松弛由于y是正无穷,所以结果z仍为正无穷;从a图中随机选择(s,y)边,进行松弛结果为y为7~~~~~等等

总结:

事实:

1、第一轮松弛只有(s,y)、(s,t)边的松弛是有效果的,其他的松弛都是无效的

事实背后的结论:

1、第n轮的松弛只能保证到s距离为n的结点得到其正确的最短路径结果

疑问:

1、那如果先随机选择到了(s,t),后选择(t,x)那么是不是(t,x)的松弛也是有效的?事实确实如此,但是我们不能保证首先松弛的是哪一个边。所以,算法导论中给我们呈现的是进行一轮松弛后至少会达到的效果

3.流程阐释

两个问题:1、对图中所有边进行一轮松弛作用是什么。2、为什么松弛要进行V-1轮。

两个思考:

1、对图中所有边进行一轮松弛作用就是让保证取到最短路径的点到s的距离增加1(第一轮后,到s最短路径为1的点都保证获得最短路径值;第二轮后,到s最短路径为2的点都保证获得最短路径值。以此类推~

2、松弛V-1轮即可是由于图中任何一个点到s的距离最长只能为V-1

算法伪代码

//Bellman-Ford伪代码
//令G(V,E),s表示单源出发点,w是每条边的权重,v是目标点,u是途径点
Bellman-Ford(G,w,s)
    for i=1 to 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
RELAX(u,v,w)
    if v.d>u.d+w(u,v)
        v.d=u.d+w(u,v)
        v.π=u

算法证明 

贝尔曼福特算法的证明包括:1、最短路径证明;2、算法返回值完整性证明

这里我们重点来看最短路径证明:1、路径松弛性质;2、最短路径证明

路径松弛性质

理解关键点: 

1、本性质的成立和松弛操作无关。也就是说这些操作不一定是连续进行的,在彼此之间可以穿插其他的松弛操作。只要按这个相对顺序进行这样一遍松弛处理,那么我们一定能够得到vk的最短路径(即使是在第一轮松弛中,我们就按这个顺序进行松弛,依旧能得到vk的最短路径)

最短路径证明

理解关键点: 

1、假如路径长为k,也就是以vk为目的点。由于没有环,所以k小于等于V-1。而我们可以进行V-1次松弛,每次松弛都是对所有边进行的。也就是说第一次松弛必然有(v0,v1),第二次松弛有(v1,v2),第三次则有(v2,v3)以此类推,最后必然可以(因为k小于等于V-1)到(vk-1,vk),也就说vk必然已经得到最短路径。证毕~~

总结

本文到这里就结束啦~~

本篇文章的撰写花了本喵两个多小时

如果仍有不够希望大家多多包涵~~如果觉得对你有帮助,辛苦友友点个赞哦~

知识来源:《算法导论》、山东大学孔凡玉老师ppt。不要用于商业用途转发哦~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

十二月的猫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值