Dijkstra贪心算法的准确性证明

简述一下Dijkstra算法

先举个例子来简述一下Dijkstra算法吧。如下图,从节点1出发,求到每个节点的最短路径在这里插入图片描述

首先获取节点1到各个节点的距离,需要注意的是,我们给算法的输入数据是一个邻接矩阵或者邻接表,从这个邻接矩阵里我们能获取到的只有相邻节点的距离(同时也是最短距离),而其余的暂时未知,全部设为无穷大。

在这里插入图片描述

接下来就是循环重复这三个动作:

在尚未被排除的节点中,找到目前与①距离最短的那个节点(姑且称这个节点为V)

比如在上图中,②③④⑤都是尚未排除的节点,从刚刚第一步的操作我们可以知道,①到②的距离是2,到③的距离是5,其余都是无穷大。那么目前与①距离最短的节点就是②,V=②

找到节点V之后的节点,把自己的路径“借”给它们,看看能不能更新它们的最短路径

②之后的节点是③和④,
先考虑③节点:从①到②的路径长度是2,而②到③的长度是2,所以“从①到②再到③”这个路径的长度是2+2=4。而如果直接从①到③,长度则是5,5大于4,显然是“从①到②再到③”这条路径更优。所以③的路径更新为“①>②>③”,长度为4。
再考虑④节点:而②到④的长度是6,所以“①>②>④”这个路径的长度是2+6=8,而如果直接从①到④,就目前掌握的数据而言,长度是无穷大。所以从①到④的路径更新为“①>②>④”,长度为8。

在这里插入图片描述
放在具体的编程里,我们就是要为每个节点都建立一组数据,定义一个结构体,包含:路径,路径长度。
但其实可以优化一下,并不需要把路径从头到尾记录下来,只需要记录这个节点的前一个节点是谁就好。比如④的前节点是②,②的前节点是①,如果你想知道从①到④的路径,就可以从④开始,④会找到②,②会找到①,就得到完整的路径了。

把检查过的节点排除掉,以后不再检查

刚刚检查了②,那么现在就可以把②排除了(图里排除的用红色圈起来了)
放在具体的编程里,我们可以建立一个集合,包含未被排除的节点:
     vector<节点指针> Vset={2,3,4,5};
然后在排除的时候直接remove
     Vset.remove(2);
上面这样写只是方便理解,实际编程还要具体考虑

如果还不理解的话可以看这位大佬的文章:Dijkstra算法详解(完美图解、趣学算法)

准确性证明

这个算法凭什么保证它求得的一定是最短路径呢?
我们可以这样思考:

在这里插入图片描述
比如我们要 求这个图中的节点⑤的最短路径,
对于节点⑤,只有两种到达它的方法,
一个是通过节点③,一个是通过节点④
“可是通过节点④的路径也有很多条呀?比如‘①>②>④>⑤’或‘①>③>④>⑤’。”
这个问题我们暂且不关心,假设我现在已经掌握了从①到④的最短路径,那么在这个前提下,我可以断定,通过这个从①到④的最短路径再到达⑤的路径,一定是在通过节点④到达节点⑤这个方法中最短的路径。

在这里插入图片描述

然后,假设我还拿到了从①到③的最短路径,那么通过这个从①到③的最短路径再到达⑤的路径,一定是在通过节点③到达节点⑤这个方法中最短的路径。
而对于这个图中的节点⑤,你只有两种方法可以到达它
要么是通过节点③,要么是通过节点④
那么只要我对比这两个“通过③的最短路径”和“通过④的最短路径”哪个更短,不就确定了从①到⑤的最短路径了吗?

如果你能理解上面的思路,那么整个问题其实已经证明完毕了。具体的推导就交由读者自己动笔吧。

但其实还有一个关键问题没有解决

你凭什么保证这个节点在被检查到之前就已经拿到了它的最短路径?

比如还是这张图的节点④(稍微改改),可以看出它的最短路径是“①>⑥>⑦>④”,那万一好巧不巧,算法先走了“①>②>④”,然后到了④,那么节点⑤就会把①>②>④>⑤当作最短路径,可实际上正确的最短路径应该是“①>⑥>⑦>④>⑤”

在这里插入图片描述
会不会出现这种情况呢? 依照算法跑一遍,发现其实不会。
为什么?
接下来就要证明:
一个节点在被检查之前,必定已经找到了它的最短路径。
<=逆否命题=>
若某一节点存在更短的路径却尚未被选中,则这个节点不可能被检查

证明开始:
让我们回顾一下这个步骤:
在尚未被排除的节点中,找到目前与①距离最短的那个节点(姑且称这个节点为V)
这个步骤它保证了什么呢?
假如现在有两条路径,红色的路径算法已经跑过了,并且知道它的长度是13;紫色的路径紫色的路径算法跑了一半,还不知道最终长度,那么算法会选择放弃紫色路径直接奔向节点④吗?答案是不会。因为2+8=10<13,下面这条没跑完的路径更短,所以算法肯定会先去跑紫色路径。

在这里插入图片描述
那么如果我现在不知道具体的数值,只知道紫色路径比红色路径短(算法程序不知道),可以保证算法一定会选紫色路径吗?

在这里插入图片描述
证:
记红色路径长度为a,紫色路径长度为b,且a>b
在程序中,紫色路径尚未跑完,假设紫色路径中途停在了某个节点V处,记录在案的路径长度为r,显然,在这条紫色路径上,从①到途经点V的距离一定小于从①到终点的距离,也就是r<b
又已知a>b,所以a>r,所以算法在检查节点④之前一定会去检查节点V
证毕

peace

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

白草遥遥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值