博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Floyd算法思想
阅读量:5816 次
发布时间:2019-06-18

本文共 1802 字,大约阅读时间需要 6 分钟。

关键词:代数、图论、矩阵、松弛技术、动态规划 

  Floyd算法是一个经典的动态规划算法。用通俗的语言来描述的话,首先我们的目标是寻找从点i到点j的最短路径。从动态规划的角度看问题,我们需要为这个目标重新做一个诠释(这个诠释正是动态规划最富创造力的精华所在),floyd算法加入了这个概念 

    Ak(i,j):表示从i到j中途不经过索引比k大的点的最短路径。 

  这个限制的重要之处在于,它将最短路径的概念做了限制,使得该限制有机会满足迭代关系,这个迭代关系就在于研究:假设Ak(i,j)已知,是否可以借此推导出Ak-1(i,j)。 

  假设我现在要得到Ak(i,j),而此时Ak(i,j)已知,那么我可以分两种情况来看待问题:1. Ak(i,j)沿途经过点k;2. Ak(i,j)不经过点k。如果经过点k,那么很显然,Ak(i,j) = Ak-1(i,k) + Ak-1(k,j),为什么是Ak-1呢?因为对(i,k)和(k,j),由于k本身就是源点(或者说终点),加上我们求的是Ak(i,j),所以满足不经过比k大的点的条件限制,且已经不会经过点k,故得出了Ak-1这个值。那么遇到第二种情况,Ak(i,j)不经过点k时,由于没有经过点k,所以根据概念,可以得出Ak(i,j)=Ak-1(i,j)。现在,我们确信有且只有这两种情况---不是经过点k,就是不经过点k,没有第三种情况了,条件很完整,那么是选择哪一个呢?很简单,求的是最短路径,当然是哪个最短,求取哪个,故得出式子: 

      Ak(i,j) = min( Ak-1(i,j), Ak-1(i,k) + Ak-1(k,j) )

  因此floyd的最外层循环:

    for (k = 0; k < n; k++) ...
  就是分别求出 A0(i,j), A1(i,j), ..., An(i,j) 

 

  算法描述:

    (1) 用数组dis[i][j]来记录i,j之间的最短距离。初始化dis[i][j],

      若i=j则dis[i][j]=0,

      若i,j之间有边连接则dis[i][j]的值为该边的权值,否则dis[i][j]的值为 。

    (2) 对所有的k值从1到n,修正任意两点之间的最短距离,计算dis[i][k]+dis[k][j]的值,若小于dis[i][j],则dis[i][j]= dis[i][k]+dis[k][j],否则dis[i][j]的值不变

程序:

1 void Floyd(int dis[n + 1][n + 1], int path[n + 1][n + 1], int n) 2 { 3     int i, j, k; 4     for (k = 1; k <= n; k++) { 5         for (i = 1; i <= n; i++) { 6             for (j = 1; j <= n; j++) { 7                 if (dis[i][k] + dis[k][j] { 8                     dis[i][j] = dis[i][k] + dis[k][j]; 9                     Path[i][j] = k;10                 }11             }12         }13     }14 }

正确性证明(归纳法) :

  对于任意两点A,B:

    (1)当从A到B之间的最短路径,在中间没有经过顶点或经过1个顶点号为1的顶点时,算法显然正确。

    (2)假设A到B经过的最大顶点号不超过k-1时,算法得到的最短距离是正确的

    (3)当A到B经过的最大顶点号为k时,则从A到顶点号为k的顶点v 之间的顶点号均不大于k-1,从v 到B之间的顶点号也不大于k-1,由假设2得,

        A到vk的距离是中间顶点号不超过k-1的最短距离,vk到B的距离是中间顶点号不超过k-1的最短距离,所以A经vk到B为A,B之间经过最大号

        为k的路径中距离最短的,由算法修正A,B的最短距离,即可得到A,B间顶点号不超过k的最短距离。

    (4)综上所述,算法是正确的

  时间复杂度:O(n3)

转载地址:http://qymbx.baihongyu.com/

你可能感兴趣的文章
git reset 三种用法总结
查看>>
虚拟机新增加硬盘,不用重启读到新加的硬盘
查看>>
Java IO流详尽解析
查看>>
邮件服务系列之四基于虚拟用户的虚拟域的邮件系统(安装courier-authlib以及部分配置方法)...
查看>>
Linux VSFTP服务器
查看>>
DHCP中继数据包互联网周游记
查看>>
Squid 反向代理服务器配置
查看>>
Java I/O操作
查看>>
Tomcat性能调优
查看>>
项目管理心得
查看>>
Android自学--一篇文章基本掌握所有的常用View组件
查看>>
灰度图像和彩色图像
查看>>
通过vb.net 和NPOI实现对excel的读操作
查看>>
TCP segmentation offload
查看>>
java数据类型
查看>>
数据结构——串的朴素模式和KMP匹配算法
查看>>
FreeMarker-Built-ins for strings
查看>>
验证DataGridView控件的数据输入
查看>>
POJ1033
查看>>
argparse - 命令行选项与参数解析(转)
查看>>