zoukankan      html  css  js  c++  java
  • 算法笔记----Floyed的k循环在最外层详解

    来自某人博客,失效了去github看
    github

    看不懂 Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。从图的带权邻接矩阵A=[a(i,j)] n×n开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。采用松弛技术(松弛操作),对在i和j之间的所有其他点进行一次松弛。所以时间复杂度为O(n^3)


    知乎上有动态规划的解释,这里给出通俗易懂的解释

     
    开始算法之前,首先介绍一下这个算法是如何运行的,e[i][j]指的是从 i 到 j 的最短路,在初始化的时候,如果着两条边直接有路相连,那么直接赋值,如果没有连接,那么就设为正无穷大,一般用一个比较大的数。然后每次比较 i 和 j 之间的中间点 k ,如果 i 到k 加上 k 到 j 的权值小于 i 直接到 j 那么 e[i][j]的值也就是 i 到 j 的最短路就变成了从e[i][k]+e[k][j]的值。
     

    循环最外层证明 

    但是为什么要先枚举k呢,为什么不能先枚举 i 然后再枚举 i 的中间点k,最后枚举 j 呢,其实这是因为,i=1,j=2时,这时k分别取1,2,…,n,这时1到3,1到4,…,3到2,4到2,…的距离都不是某种意义上最短的,而这个新算法却直接使用了他们,并且再也没有回头重新计算i到j的距离是否因为其他节点间距离的改变而更短,所以这样算出来的值也就没有什么意义。 

    如图

    在上面这个图中枚举i=A,j=B,然后循环,正确的A到B最小是3,然而你更新的是125,

    因为最短那个不是只有一个中介点,所以就没更新

    因为你在枚举下一个i之后,就不会再次回去了,所以说A,B之间的最短路就被定为了125,以后也会以e[i][j]=125去更新其他的点,所以说,k循环必须放在最外层,不然会有可能无法找到最优值。













    种一棵树最好的时间是十年前,其次是现在。
  • 相关阅读:
    【Mysql】Mysql常见的日志种类及作用
    【Mysql】执行sql的过程
    【Mysql】回表查询原理,利用联合索引实现索引覆盖
    【Mysql】explain详解与索引最佳实践
    【Mybatis】MyBatis源码编译
    【Mysql】MySQL数据存储文件详解
    【LoadRunner-工作原理】
    【LoadRunner-简介】
    【LoadRunner-基础篇】
    【LoadRunner-基础篇】
  • 原文地址:https://www.cnblogs.com/islch/p/12598616.html
Copyright © 2011-2022 走看看