floyd最短路径算法 java_图论动态规划算法——Floyd最短路径

Floyd算法

Floyd是一种经典的多源最短路径算法,它通过动态规划的思想来寻找给定加权图中的多源点之间的最短路径,算法时间复杂度是O(n3)。之所以叫Floyd是因为该算法发明人之一是Robert Floyd,他是1978年图灵奖获得者,同时也是斯坦福大学计算机科学系教授。

170394cf313e0d09c8dcd5102054acd2.png

核心思想

对于n个点的加权图,从加权图的权值矩阵开始,递归地更新n次最终求得每两点之间的最短路径矩阵。即加权图的邻接矩阵为 $D = (d_{ij}){_{nn}}$ 按一定公式对该矩阵进行递归更新,初始时矩阵为D(0),第一次,根据公式用D(0)构建出矩阵D(1);第二次,根据公式用D(1)构建出矩阵D(2);以此类推,根据公式用D(n-1)构造出矩阵D(n),D(n)即为图的距离矩阵,i行j列表示顶点i到顶点j的最短距离。

动态规划

如何理解这种动态规划算法呢?可以理解为逐一选择中转点,然后针对该中转点,所有以此为中转点的其它点都要根据规定进行更新,这个规定就是原来两点之间的距离如果通过该中转点变小了则更新距离矩阵。比如选择“1”作为中转点,原来“02”之间的距离为5,通过中转点1后(即路径变为“012”)距离为4,变小了,那么就更新距离矩阵对应的元素,由5更新为4。当图中所有顶点都被作为中转点处理以后,那么得到的最后距离矩阵就是多源最短距离矩阵了。

设 $c(i,j,k)$ 为i到j的中间节点编号不超过k的最短距离,当k=0时,$c(i,j,0)=d_{ij} $,对于n个顶点的图,我们要求的i到j的最短距离即是$c(i,j,n−1)$。

现在我们建立 $c(i,j,k)c(i,j,k) c(i,j,k)$ 之间的递归关系,对于任意k,$c(i,j,k)=min(c(i,j,k−1),c(i,k,k−1)+c(k,j,k−1))$,于是可以根据该递归关系得到最终的最短路径,即中间节点编号不超过n-1的最短距离。

算法过程

从任意一条单边路径开始,所有两点之间的距离是边的权重,如果两点之间没有边相连,则权重为无穷大。即用数组 $D = (d_{ij}){_{nn}}$ 来记录i,j之间的最短距离,初始时,若i=j则dis[i][j]=0。若i、j两点之间相连则dis[i][j]的值为该边的权值。若i、j两点没有相连则dis[i][j]的值为无穷。

对于每一对顶点u和v,看看是否存在一个顶点w使得从u到w再到v比已知的路径更短,如果存在则更新。即对所有的k值(1

神奇的五行代码

Floyd算法核心就是下列五行代码,可以体会一下,三个for循环嵌套,最外层的k即是循环取不同中转点时的情况,分别让图中每个顶点作为中转点去更新距离,完成所有循环后就是最终的最短距离矩阵。

for(k=1;k<=n;k++)

for(i=1;i<=n;i++)

for(j=1;j<=n;j++)

if(d[i][k]+d[k][j]

d[i][j]=d[i][k]+d[k][j];

优缺点

优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单。对于稠密图效果最佳,边权可正可负。

缺点:时间复杂度比较高,不适合计算大量数据。

执行过程

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值