🌈 个人主页:十二月的猫-CSDN博客
🔥 系列专栏: 🏀算法启示录💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光
目录
前言
最短路径算法是图论中一类重要算法,其功能就如名字一样——求解点与点之间最短距离。
首先,先让我们对最短路径算法有一个概观,看看都有哪些种类的最短路径算法,每一个种类中代表的算法又是什么。
单源最短路径算法:从一个起点出发求解其到其他所有其他点的最短距离
多源最短路径算法:从所有点出发求解其到其他所有其他点的最短距离
松弛视角
关键点:
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。不要用于商业用途转发哦~