以下所有讨论,都是基于有向无负权回路的图上的。因为这一性质,任何最短路径都不会含有环,所以也不讨论路径中包含环的情形!并且为避免混淆,将“最短路径”称为权值最小的路径,将路径经过的点数-1称为路径的长度。

先列出算法的c语言代码实现,后面将用这段代码来辅助证明。

  1. int n;//从1..n共n个点
  2. int dis[maxn][maxn];//权值邻接矩阵
  3. init();//初始化数据
  4. for(int k=1;k<=n;++k)
  5. for(int i=1;i<=n;++i)
  6. for(int j=1;j<=n;++j)
  7. dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);

先用比较形象的语言来简单叙述一遍。

  • 以下“每次更新路径”指k=k_i时内层的两重循环,k是每次更新路径采用的“中间点”。
  • 每个点k在被用作中间点时,相关路径的最小权值,已经被继承到本次更新的路径里了。其他没有被更新的点想通过k进行连接,就一定包含本次更新的路径。并且后续只保留任意两个端点间权值最小的那条路径进行计算。
  • 因此在更新n次后,与所有点的相关路径的最小权值,都已经更新完毕。也就是说,所有的路径都已经考虑并更新过了。

下面是比较符号化的严谨证明。

  • 设共有\(1..n\)共\(n\)个点,初始化所有长度为1的路径集合为\(R\),\(x\)与\(y\)的当前最小路径权值为\(dis[x][y]\),这个最小权值对应\(R\)中的一条路径\(x,r_1,r_2,...,y\)。
  • 现在采用数学归纳法,以\(k=1..n\)进行\(n\)次路径扩展,并更新\(R和dis[][]\)。
  • 当\(k=1\)时,\(R\)中已经包含所有顶点两两连接的路径。选取所有的路径\(x,k和k,y\),进行连接得到\(G\{d|d=x,k,y\}\)。\(R=R\cup G\),更新\(dis[][]\)。

    这样,\(R\)中就包含了:起点与终点之间(不包含起点、终点),仅含点1的所有路径。因为没有负权回路,所以后续更新的多次经过点1的路径都不影响最小权值性质,并且也可以被R中去除路径中回路部分的路径替代(不影响其连接作用且权值更小,以下将不再讨论有回路的路径情况)。
  • 假设当\(k=1..n\)时,\(R\)中已经包含:起点与终点之间(不包含起点、终点),仅含\(1..k-1\)的所有路径。令\(r_k=k\),选取R中的所有起点为\(k\)的路径\(S\{d|d=x,r_1,r_2,...r_k\}\),和所有以\(k\)为终点的路径\(T\{d|d=r_k,r_k+1,...y\}\),让\(S\)与\(T\)中的路径两两连接,得到\(G\{d|d=x,...,r_k,...,y\}\)。然后令\(R=R\cup G\),更新\(dis[][]\)。这样,\(R\)中就已经包含了:起点与终点之间(不包含起点、终点),仅含\(1..k\)的所有路径。原假设成立。
  • 上述做法进行到\(k=n\)结束,\(R\)中就已经包含了这个图所有的路径连接可能。而更新\(dis[][]\)的步骤,因为所有的\(R\)中的路径对应的\(dis[i][k]\)和\(dis[k][j]\)都在之前计算过了,所以实际上每轮就只需计算\(dis[i][j]=min\{dis[i][j],dis[i][k]+dis[k][j]\}\)。

在做作业的时候遇到这个算法,想起来好像一直在用但并不理解它的正确性,所以尝试证明了一下。正好也作为我写博客的一个开头吧。

Floyd-Warshall算法正确性证明的更多相关文章

  1. Floyd—Warshall算法

    我们用DP来求解任意两点间的最短路问题 首先定义状态:d[k][i][k]表示使用顶点1~k,i,j的情况下,i到j的最短路径 (d[0][i][j]表示只使用i和j,因此d[0][i][j] = c ...

  2. 图论之最短路径(1)——Floyd Warshall & Dijkstra算法

    开始图论学习的第二部分:最短路径. 由于知识储备还不充足,暂时不使用邻接表的方法来计算. 最短路径主要分为两部分:多源最短路径和单源最短路径问题 多源最短路径: 介绍最简单的Floyd Warshal ...

  3. Gym 101873D - Pants On Fire - [warshall算法求传递闭包]

    题目链接:http://codeforces.com/gym/101873/problem/D 题意: 给出 $n$ 个事实,表述为 "XXX are worse than YYY" ...

  4. Floyd最短路径算法

    看完这篇文章写的小程序,Floyd最短路径算法,求从一个点到另一个点的最短距离,中间可以经过其他任意个点.三个for循环,从i到j依次经过k的最短距离,最外层for循环是经过点K,内部两个循环是从i( ...

  5. WarShall算法

    1.引言 图的连通性问题是图论研究的重要问题之一,在实际中有着广泛的应用.例如在通信网络的联通问题中,运输路线的规划问题等等都涉及图的连通性.因此传递闭包的计算需要一个高效率的算法,一个著名的算法就是 ...

  6. [C++]动态规划系列之Warshall算法

    /** * * @author Zen Johnny * @date 2018年3月31日 下午8:13:09 * */ package freeTest; /* [动态规划系列:Warshall算法 ...

  7. POJ 2253 Frogger(warshall算法)

    题意:湖中有很多石头,两只青蛙分别位于两块石头上.其中一只青蛙要经过一系列的跳跃,先跳到其他石头上,最后跳到另一只青蛙那里.目的是求出所有路径中最大变长的最小值(就是在到达目的地的路径中,找出青蛙需要 ...

  8. Warshall算法求传递闭包及具体实现

    传递闭包 在数学中,在集合 X 上的二元关系 R 的传递闭包是包含 R 的 X 上的最小的传递关系. 例如,如果 X 是(生或死)人的集合而 R 是关系“为父子”,则 R 的传递闭包是关系“x 是 y ...

  9. Floyd最短路径算法(来自微信公众号“算法爱好者”改编)

    暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有4个城市8条公路,公路上的数字表 ...

  10. Algorithm --> Dijkstra和Floyd最短路径算法

    Dijkstra算法 一.最短路径的最优子结构性质 该性质描述为:如果P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,k和s是这条路径上的一个中间顶点,那么P(k,s)必 ...

随机推荐

  1. jQuery实现回车键抬起触发事件

    $(function(){ //回车键按下触发 $(document).keydown(function(event){ if(event.keyCode==13){ alert("niha ...

  2. 掌握使用gitlab ci构建Android包的正确方式

    最近公司在做移动端的项目,自然而然的需要搭建打包的环境.本来计划用Jenkins的,但是发现在gitlab上创建完项目后,提示去配置pipeline,于是决定用gitlab去尝试下,毕竟我觉得Jenk ...

  3. 安装elasticsearch-head(源码安装方式)

    gitHub 地址 https://github.com/mobz/elasticsearch-head 克隆到本地 进行npm 安装运行 git clone git://github.com/mob ...

  4. C++primer(第五版)Sales_item.h头文件

    C++primer(第五版)1.51练习章节需要有一个Sales_item类,但是给的网站找不到,直接复制下面就好咯: #ifndef SALESITEM_H #define SALESITEM_H ...

  5. python--爬虫之JSON于JsonPath

    JSON json的引入 在python中json作为一个内建库不需要额外安装,只需要使用import json执行引入 json模块的功能 在python中json模块提供了四个功能:dumps.d ...

  6. 了解这5大K8S管理服务,为你节省50%的部署时间!

    Kubernetes已然成为IT世界的重要组成部分,并且仍在不断地发展壮大,现阶段,Kubernetes已经可以帮助企业进行微服务训练,加速企业数字化转型.尽管Kubernetes是一款如此令人印象深 ...

  7. 用ASP.NET MVC5 +SQLSERVER2014搭建多层架构的数据库管理系统

    用http://ASP.NET MVC5 +SQLSERVER2014搭建多层架构的数据库管理系统 背景:前段时间,给一家公司做外包(就是图标是朵菊花那家).为了尽快实现交付,网上四处寻找适合中小型企 ...

  8. networkx学习与攻击转移图可视化

    接到一个任务,将攻击转移矩阵进行可视化,生成攻击转移概率图,便尝试用python实现一下. 查阅资料,看大家都在用networkx和matplotlib进行可视化,便边学边做,记录一下学习笔记. 任务 ...

  9. string 从下标0 一直截到倒数第三位

    StringUtils.substring(String.valueOf(maxSequence), 0, -3)如上,关键就是那个-3,表示倒数第三位.

  10. 多级菜单初写(dict使用)

    #!/usr/bin/env python3# -*- coding:utf-8 -*-# name:zzyumap = { "中国":{ "北京":{ &qu ...