Dijkstra 算法正确性证明

Toretto·2024-08-10 17:07·195 次阅读

Dijkstra 算法正确性证明

Dijkstra正确性证明

Dijkstra算法的本质#

如果你有思考“为什么”的习惯,就一定会发现,Dijkstra 的本质就是动态规划 + BFS 。松弛操作实际上就类似于动态规划中的状态更新。

f(u)su 的最短路径( s 为源点,下文同)。显然,状态转移方程为:

f(u)=minvfathersf(v)+wu,v

其中,fathers 表示所有点 v 使得存在边 e=vuwu,v 则表示该边的权。

这个状态转移方程是显然的,是非常经典的“退一步思考”,即思考点 u 是父节点中哪个点来的。既然我们求的是最短路,当然是能让整条路径最小的那一点。

而 Dijkstra 中,则引入了一切别的策略,本质上都只是优化。

正文#

好了,实际上前文和正文都没关系,只是想要分享一下我对于一个算法的理解。

我们重新回忆算法每一步都干了什么:

  1. 在未确定最短路集合 T 中,选择估计最短路最短的点,将其移动至已确定最短路集合 S 中。
  2. 利用此点,更新邻近的点(松弛)。

我们无非就是需要证明,每次从 T 集合中拿出的点的估计最短路 dis(u) 与实际最短路 D(u) 相等。

使用反证法,假设此结论不成立,设 e 点是第一个从 T 点中拿出而 dis(e)D(e) 。我们知道,估计最短路一定大于或等于实际最短路,即 dis(e)D(e)

整理,得 dis(e)>D(e)

首先讨论一下第一个点能否不满足此结论。

算法刚开始,T 的每个点都为 + 。随后,Ts 被修改为 0 。

那么,第一次拿出的点一定是 sdis(s)=D(s)=0 ,满足结论,即 es

接下来讨论不存在 se 的路径时(即 D(s)=+ 时),是否满足结论:

此算法的 Tedis(e) 的更新依赖于父节点的松弛操作。

若父节点也未曾更新,Tedis(e) 也都未更新,dis(e)=D(e)=+

若父节点更新过,意味着父节点的父节点也会有更新。不断追溯,发现,最初的更新来源于源点。

也就是说,若父节点更新,是从源点开始一路更新到父节点。那么意味着父节点存在一条路径 sfather

e 点的父节点存在路径,那么 e 点也一定存在一条路径 sfathere 。与讨论条件矛盾。

所以,若 e 点不存在与 s 点的路径时,结论成立。

也就是说 e 点一定存在一条路径 se

那么讨论一下该路径的性质。

因为 e 是第一个出错的点,所以在此之前,所有 uS 都满足 dis(u)=D(u)

若所有 se 的路径上的所有点都满足 uS ,显然 dis(e)=D(e) 与假设矛盾。

所以一定有一条路径 sxye ,其中,y 是路径上第一个属于 T 的点。那么 x 就一定满足 xS

刚才已经提到,x 一定满足 dis(x)=D(x) 。此时会更新 y 。可以证明,当 e 被取走时,dis(y)=D(y)

dis(y)=D(y)D(e)<dis(e)

但是因为过程 1 的条件,e 被取走时, e 一定是估计最短路最小的,而 y 没有取走,在比较范围内,所以一定有 dis(y)dis(e)

但此与前文不等式链相矛盾,所以假设不成立,命题得证。

本证明大部分都取自 OI Wiki .

posted @   LiserverYang  阅读(195)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示
目录