欢迎光临散文网 会员登陆 & 注册

数据结构与算法_最短路径之Floyd算法

2023-03-01 22:37 作者:昵昵酱紫  | 我要投稿

Dijkstra算法是求源点到其他各个顶点的最短路径,如果求解任意两个顶点的最短路径,则需要以每个顶点为源点,重复调用n次Dijkstra算法。完全没有必要这么麻烦,下面介绍的Floyd算法可以求解任意两个顶点的最短路径。Floyd算法又称为插点法,其算法核心是在顶点i到顶点j之间,插入顶点k,看是否能够缩短i和j之间的距离(松弛操作)。

算法步骤:

1)数据结构。

设置地图的带权邻接矩阵为G.Edge[ ][ ],即如果从顶点i 到顶点j有边,就让G.Edge[i][j] = <i,j>的权值,否则G.Edge[i][j] = 无穷大;采用两个辅助数组;最短距离数组dist[ i][j],记录从i 到j顶点的最短路径长度;前驱数组p[i][j],记录从 i 到j顶点的最短路径上j顶点的前驱。

2)初始化。

初始化dist[i][j] = G.Edge[i][j],如果顶底i 到顶点j 有边相连,初始化p[i][j] = i,否则p[i][j] = -1。

3)插点。

其实就是在i,j之间插入顶点k,看是否能够缩短i和j之间距离(松弛操作)。如果dist[i][j] >dist[i][k] +dist[k][j],则dist[i][j] = dist[i][k] + dist[k][j],记录顶点j 的前驱为:p[i][j] = p[k][j]。

一个例子:

1)数据结构:

设置地图的带权邻接矩阵为G.Edge[ ][ ],即如果从顶点i 到顶点j有边,就让G.Edge[i][j] = <i,j>的权值,当 i = j 时, G.Edge[i][j] = 0,否则G.Edge[i][j] = 无穷大。

2)初始化

初始化最短距离数组dist[i][j] = G.Edge[i][j] ;如果顶点i 到 j有边相连,初始化前驱数组p[i][j] =i,否则p[i][j] = -1。初始化后的dist[ ]和p[ ][ ],如图所示:

3)插点(插顶点0,k=0)

其实就是借点,借东风,大家一起借顶点0更新最短距离。如果dist[i][j] > dist[i][0]+dist[0][j],则dist[i][j] = dist[i][0] + dist[0][j],记录顶点j的前驱为:

p[i][j] = p[0][j]。

谁可以借顶点0呢?

看顶点0的入边,2--->0,也就是说顶点2可以借0点,更新2到其他顶点的最短距离。(程序中通过穷举所有顶点来判断是否可以借0点)。

dist[2][1]:    dist[2][1] = 5 > dist[2][0] + dist[0][1] = 4,则更新dist[2][1] = 4,p[2][1] = 0;如图所示:


4)插点(插顶点1,k = 1)

大家一起借顶点1更新最短距离。谁可以借顶点1呢?

看顶点1的入点,顶点0、2都可以借1点,更新其到其他顶点的最短距离。

dist[0][2]:    dist[0][2] = 无穷大 > dist[0][1] +dist[1][2] = =10,则更新dist[0][2] = 10,p[0][2] = 1;

5)插点(插顶点2,k=2)

大家一起借顶点2,更新最短距离。从顶点2的入边可知,1,3可以借。

6)插点(插顶点3,k=3)

大家一起借顶点3,更新最短距离。看顶点3的入边,顶点0、1、2都可以借3点。

7)插点结束。

dist[][]数组即为各顶点之间的最短距离,如果想找顶点i 到顶点j的最短路径,可以根据前驱数组p[][]获得。

例如:

1)求1到2的最短路径,首先读取p[1][2] = 3,说明顶点2的前驱为3,继续向前找,读取p[1][3] = 1,说明3的前驱为1,得到1到2的最短路径为1-> 3->2。

2)求1到0的最短路径,首先读取p[1][0] = 2,说明顶点0的前驱为2,继续向前找,读取p[1][2] = 3,说明2的前驱为3,继续向前找,读取p[1][3] =1,得到1到0的最短路径为1->3->2->0。



数据结构与算法_最短路径之Floyd算法的评论 (共 条)

分享到微博请遵守国家法律