对Floyd算法的理解

Floyd算法(弗洛伊德算法)是用来计算带权图的多源最短路径算法。

设存储图的邻接矩阵为二维数组a[n][n],则其算法伪码可描述如下:

Floyd:
for (k = 0; k < n; k++)
   for (i = 0; i < n; i++)
      for (j = 0; j < n; j++)
         if (a[i, j] > a[i, k] + a[k, j])
            a[i, j] = a[i, k] + a[k, j]


这里从Floyd算法能否找出最短路径进行理解,以a[1, 2]为例。

这里分为如下四种情况进行说明:

1)a[1, 2]不可达,易于理解,不再说明;

2)a[1, 2]直达,易于理解,不再说明

3)a[1, 2]通过某一点进行中转,如点3,记该最短路径为点的序列(1, 3, 2);

4)a[1, 2]通过某些点进行中转,如点5,、3、4,记该最短路径为点的序列(1,5,3,4,2);

这里从情况(3)开始说明。

看Floyd算法的伪码,一个共包含三个循环,但可以很明显的分成两个部分。第一部分为内层的两个循环,遍历的是所有的点对;第二部分是最外层的那个循环,遍历的是所有的点。那么最直观上的理解就是,对所有点对之间的最短路径,都尝试通过某一点来进行中转,并由此更新最短路径。

那么,明显可以看到的是,在k = 3时,通过a[1, 2]与(a[1, 3]+a[3, 2])的比较可以确定出第三种情况下的最短路径。

关键在于情况(4)的理解。

在情况(3)中,对于经过某一点p进行中转的最短路径,通过k = p的执行即可理解Floyd对该路径的寻找,但是如情况(4)中,经过多点的中转便不易通过一次执行来理解。这里通过对算法的依次执行来进行理解。

对于路径(1,5,3,4,2)(这里假设该路径即是点1到点2的最短路径,并阐述Floyd算法是如何找到这条最短路径的):

当k = 3时,会有a[5, 4] = a[5, 3] + a[3, 4],并且已经可以确定(5,3,4)已经是点5到点4的最短路径了(因为如果存在另外一条更短点5到点4的路径,则有悖于对点1到点2最短路径的假设)。

当k = 4时,会有a[5, 2] = a[5, 4] + a[4, 2],虽然此时看起来像是(5,4,2),但从上一步中我们知道a[5, 4]中存储的其实是路径(5,3,4)的长度。所以,此时a[5, 2]代表的其实是路径(5,3,4,2)。

当k = 5时,会有a[1, 2] = a[1, 5] + a[5, 2],此时便找到了(1,5,3,4,2)这条路径(此时,式中a[5, 2]代表的是路径(5,3,4,2)的长度)。

从上述的叙述中可以看到,对于任意两点之间存在的一条最短路径,Floyd算法都可以找到这条路径。

而且可以看到的是,该算法对于循环嵌套的顺序,以及循环遍历的顺序都没有要求。

最后指出的是,第一部分循环(即对k的循环)和第二部分循环(即对i、j的循环),两部分循环的顺序不可颠倒。而对于k的遍历顺序则没有要求,无论是増序遍历(++i)、降序遍历(--i),或是任何无序的遍历。

这是我的理解,如有错误请指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值