Floyd算法

网上有很多floyd算法,但我太笨了,没有几篇文章能让我看明白flody算法的原理的,说实话floyd算法实现很简单嘛,就三个for循环就能搞定,核心代码也只有5,6行的样子。
我相信看这篇文章之前,大家已经看过很多有关flody的算法。最近做实验又涉及到floyd算法,花时间去琢磨,大致明白了。
讲的不专业,见谅。
设一个N阶矩阵,用二维数值a[N+1][N+1]表示
下面是核心算法:

for(k=1;k<=N;k++)
  for(i =1;i<=N;i++)
     for(j=1;j<=N;j++)
         a[i][j] = min(a[i][j],a[i][k]+a[k][j]); 

在二维数值中,求在两个点(i,j)之间求最短路径,求解的方法无非是,比较两点直接可以到达的距离即a[i][j],和通过(在起点通过一个间接点到终点)这种间接到达终点的方式的距离即a[i][k]+a[k][j] (k属于[1,N],k为整数),寻找这些路径中的最短路径。即若通过的路径比原来的路径短,则更新路径长度。
假设此时N=5.
首先整个问题有最优子结构性质,若<v1,v5> = <v1,v2>+<v2,v3>+<v3,v4>+<v4,v5>,那么其中的<v1,v2>,<v2,v3>,<v3,v4>,<v4,v5>必须也是最优的。
我觉得弄不明白的同学应该有这么一种疑惑,若<v2,v5> = <v2 ,v4>+<v4,v5>,如何确定此时的<v2,v4>和<v4,v5>已经到达最小了呢?最外面一层for循环有什么作用呢?
最外面的for循环的第一个作用,让我们实现比较间接距离a[i][k]+a[k][j]和直接距离a[i][j]的大小,确定两种距离中的最小距离。
最外面的for循环的第二个作用,还是以上面的例子,当k=1时,若<v2,v5> = <v2 ,v4>+<v4,v5>,当k=2,若再求min(<v2,v5>)时,再计算<v2,v4>+<v4,v5>,此时的<v2,v4>和<v4,v5>可能已经被更新了。即<v2,v4>可能=<v2,v1>+<v1,v4>,<v4,v5>可能=<v4,v1>+<v1,v5>(因为经过了k=1的情况),假设此时的<v2,v4>=<v2,v1>+<v1,v4>则<v2,v5>=<v2,v1>+<v1,v4>+<v4,v5>,每当k++时,矩阵中每个点都可能进行更新,即插入新的点,当k=N,即k=5时,而此时每个点之间的路径最多可以插入了N-1个点,即4个点,也可以说成插入4条边,则我们可以考虑到若v2要经过所有点才能到达v5时,假设<v2,v5>=<v2,v1>+<v1,v4>+<v4,v3>+<v3,v5>此时只需要插入两条边即可。4>2所以包含了要插入所有边和点的情况。事实上也不可能出现出现插入3条边或4条边的情况,因为这样必定会出现环,从某个点出发又回到某个点,但是路径中有环是不可能出现的(因为<Vi,Vi>=0小于等于<Vm,Vn>)
大家还有可能有这样的担心,这样的情况发生<v1,v5>=<v1,v3>+<v3,v5>,<v1,v3> =<v1,v5>+<v5,v3>,两个式子会产生相互的影响。其实这种情况是不可能出现的,因为出现了环。把其中一个式子带入另一个式子,而<v1,v5>显然小于<v1,v5>+<v5,v3>+<v3,v5>,所以这种情况不可能出现。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值