一个关于dijkstra算法正确性的证明

本文详细解释了Dijkstra算法的工作原理,通过归纳法证明了在非负权值图中,算法找到的distance_now[u]确实表示从起点到u的最短路径。作者分析了算法过程,并使用反证法确保了新加入节点的distance_now是最短路径。
摘要由CSDN通过智能技术生成

dijkstra算法的证明

一直没法证明为什么该算法求出的就能是最短路径,看了很多别的博客想了很久,提出来一个证明方法,望指正

一.归纳前的符号准备

符号含义初值
visited[u]u 是否已经纳入已确定最短路径的集合false
distance_now[u]u 现在到达起点的最短距离(计算过程中会一直更新) + ∞ +\infty +
distance_short[u]u 到起点的最短距离(实际上的答案)ans
visited集合已经纳入已确定最短路径的点的集合\
un_visited集合尚未纳入已确定最短路径的点的集合\
dis[i] [j]从i到j的边权

二.关于dijkstra算法的过程描述

  1. 将起点u放入visited集合

  2. 利用u更新其他所有节点的distance_now,更新方式为distance_now[v] = min{distance_now[v],distance_now[u]+distance[u] [v]}

    即取:通过s~中转到u的距离与原距离的最小值

  3. 从un_visited集合中,找出最小的distance_now[u],将u点从un_visited移除,加入visited中

  4. 重复2和3直至终点已被纳入visited集合,即可得出起点到终点的最短距离

三.证明

1.命题描述

算法纳入n个点时,visited集合(此时有n个节点)中的每个节点i的distance_now[i]等于最短路径distance_short[i]

2.归纳基础

当n=1时,纳入的是起点s,且distance[s]=0,是最短路径

3.归纳假设

假设当n=k时,假设成立,即算法纳入k个点时,visited集合(此时有k个节点)中的每个节点i的distance_now[i]等于最短路径distance_short[i]

那么,当n=k+1时,visited集合(此时有k+1个节点)中的每个节点i的distance_now[i]等于最短路径distance_short[i]也成立

引入定理
  1. 最短路径的子路径也是最短路径
  2. 如果从s到k+1的最短路径L的节点不全在visited集合中,记L经过的visited集合中的最后一个节点为last,则last与v必然不直接相连
    证明:若直接相连,则该L = distance_short[last]+dis[last] [k+1] 然而在集合visited加入last节点之后,对以last为中转节点的所有distance_now进行了更新,distance_now[k+1]必然<= distance_short[last]+dis[last] [k+1] ,distance_now[k+1]比L更小,这与L是最短路径矛盾,所以节点last必然不可能与k+1直接相连
反证法

在这里插入图片描述

  1. 如果假设不成立,那么这个不成立假设只会是
    加入的第k+1点的距离distance_now[k+1]不是最短路径

  2. 那么存在一条从s到k+1的最短路径L,这条路径的点并不全在visited集合中(如果全部存在visited中,因为是在纳入k个点后进行了距离更新,这个dis就是由visited集合中的点进行更新的,就是最短路径)

  3. 记L上最后一个在visited集合中的节点为last,那么L=distance_short[last]+从last到k+1的最短距离> distance_short[last] (非负权值图中last到k+1的最短距离肯定大于0)

  4. 由定理2可得:如果从s到k+1的最短路径L的节点不全在visited集合中,记L经过的visited集合中的最后一个节点为last,则last与v必然不直接相连,不妨设last与k+1中隔了m个节点(以下仅针对m=1时候做出证明,容易得出当m>1时也成立)

  5. 设隔的这个节点为y,那么在这里y与last直接相连

  6. 由定理1:最短路径的子路径也是最短路径,那么distance_short[last]+dis[last] [y]也是最短路径

  7. 但是由定理2可得:如果从s到y的最短路径L的节点不全在visited集合中,记L经过的visited集合中的最后一个节点为last,则last与y必然不直接相连
    这与y与last直接相连矛盾

  8. 所以加入的第k+1点的距离distance_now[k+1]不是最短路径这一假设不成立,所以加入的第k+1点的距离distance_now[k+1]是最短路径

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值