floyd算法_最短路径的算法:Floyd算法

Floyd算法详解
本文介绍了一种用于寻找加权图中顶点间最短路径的算法——Floyd算法。核心思想是从图的权值矩阵出发,通过递归更新求得每两点间的最短路径矩阵。文章还提供了算法的具体步骤、实现代码及示例。

b00ab1a44fdf21aee20e33607e5fa5a7.gif

点击箭头处“蓝色字”,关注我们哦!!

算法

最短路径的算法-Floyd算法

● ○ ●

Shortest Path Algorithm - Floyd Algorithm

● ○ ●

Floyd算法又称为弗洛伊德算法,插点法,是一种用于寻找给定的加权图中顶点间最短路径的算法

❉❉❉❉❉❉❉❉❉❉

核心思想

通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。从图的带权邻接矩阵A=[a(i,j)] n×n开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。182db08d9e3c6c8c9f049440edae120d.png

算法描述

a) 初始化:D[u,v]=A[u,v]b) For k:=1 to n    For i:=1 to n     For j:=1 to n      If D[i,j]>D[i,k]+D[k,j] Then       D[i,j]:=D[i,k]+D[k,j];c) 算法结束:D即为所有点对的最短路径矩阵
c00f8f9be4356f2192c383d6c9465c4b.png

算法过程

  • 把图用邻接距阵G表示出来,如果从Vi到Vj有路可达,则G[i,j]=d,d表示该路的长度;否则G[i,j]=空值。

  • 定义一个距阵D用来记录所插入点的信息,D[i,j]表示从Vi到Vj需要经过的点,初始化D[i,j]=j。

  • 把各个顶点插入图中,比较插点后的距离与原来的距离,G[i,j] = min( G[i,j], G[i,k]+G[k,j] ),如果G[i,j]的值变小,则D[i,j]=k。

  • 在G中包含有两点之间最短道路的信息,而在D中则包含了最短通路径的信息。

比如,要寻找从V5到V1的路径。根据D,假如D(5,1)=3则说明从V5到V1经过V3,路径为{V5,V3,V1},如果D(5,3)=3,说明V5与V3直接相连,如果D(3,1)=1,说明V3与V1直接相连。182db08d9e3c6c8c9f049440edae120d.png

时间复杂度

O(n^3)

182db08d9e3c6c8c9f049440edae120d.png

优缺点分析

Floyd算法适用于APSP(All Pairs Shortest Paths),稠密图效果最佳,边权可正可负。此算法简单有效,由于三重循环结构紧凑,对于稠密图,效率要高于执行|V|次Dijkstra算法。优点: 容易理解,可以算出任意两个节点之间的最短距离,代码编写简单;缺点: 时间复杂度比较高,不适合计算大量数据。182db08d9e3c6c8c9f049440edae120d.png

算法实现

C语言源代码

#include#define Maxm 501using namespace std;ifstream fin("APSP.in");ofstream fout("APSP.out");int p,q,k,m;int Vertex,Line[Maxm];int Path[Maxm][Maxm],Map[Maxm][Maxm],Dist[Maxm][Maxm];void Root(int p,int q){  if (Path[p][q]>0)  {    Root(p,Path[p][q]);    Root(Path[p][q],q);  }  else   {    Line[k]=q;    k++;  }}int main(){  memset(Path,0,sizeof(Path));  memset(Map,0,sizeof(Map));  memset(Dist,0,sizeof(Dist));  fin >> Vertex;  for(p=1;p<=Vertex;p++)    for(q=1;q<=Vertex;q++)    {      fin >> Map[p][q];      Dist[p][q]=Map[p][q];    }  for(k=1;k<=Vertex;k++)    for(p=1;p<=Vertex;p++)      if (Dist[p][k]>0)    for(q=1;q<=Vertex;q++)      if (Dist[k][q]>0)      {        if (((Dist[p][q]>Dist[p][k]+Dist[k][q])||(Dist[p][q]==0))&&(p!=q))        {          Dist[p][q]=Dist[p][k]+Dist[k][q];          Path[p][q]=k;        }      }  for(p=1;p<=Vertex;p++)  {    for(q=p+1;q<=Vertex;q++)    {      fout << "\n==========================\n";       fout << "Source:" << p << '\n' << "Target " << q << '\n';       fout << "Distance:" << Dist[p][q] << '\n';      fout << "Path:" << p;      k=2;      Root(p,q);      for(m=2;m<=k-1;m++)        fout << "-->" << Line[m];        fout << '\n';        fout << "==========================\n";    }  }fin.close();fout.close();return 0;}
注解:无法连通的两个点之间距离为0;输入:Sample Input
700 20 50 30 00 00 0020 00 25 00 00 70 0050 25 00 40 25 50 0030 00 40 00 55 00 0000 00 25 55 00 10 7000 70 50 00 10 00 5000 00 00 00 70 50 00
输出:Sample Output
==========================Source:1Target 2Distance:20Path:1-->2====================================================Source:1Target 3Distance:45Path:1-->2-->3====================================================Source:1Target 4Distance:30Path:1-->4====================================================Source:1Target 5Distance:70Path:1-->2-->3-->5====================================================Source:1Target 6Distance:80Path:1-->2-->3-->5-->6====================================================Source:1Target 7Distance:130Path:1-->2-->3-->5-->6-->7====================================================Source:2Target 3Distance:25Path:2-->3====================================================Source:2Target 4Distance:50Path:2-->1-->4====================================================Source:2Target 5Distance:50Path:2-->3-->5====================================================Source:2Target 6Distance:60Path:2-->3-->5-->6====================================================Source:2Target 7Distance:110Path:2-->3-->5-->6-->7====================================================Source:3Target 4Distance:40Path:3-->4====================================================Source:3Target 5Distance:25Path:3-->5====================================================Source:3Target 6Distance:35Path:3-->5-->6====================================================Source:3Target 7Distance:85Path:3-->5-->6-->7====================================================Source:4Target 5Distance:55Path:4-->5====================================================Source:4Target 6Distance:65Path:4-->5-->6====================================================Source:4Target 7Distance:115Path:4-->5-->6-->7====================================================Source:5Target 6Distance:10Path:5-->6====================================================Source:5Target 7Distance:60Path:5-->6-->7====================================================Source:6Target 7Distance:50Path:6-->7==========================
Matlab源代码
function [D,R]=floyd(a)n=size(a,1);D=afor i=1:n   for j=1:n     R(i,j)=j;   endendRfor k=1:n   for i=1:n      for j=1:n         if D(i,k)+D(k,j)            D(i,j)=D(i,k)+D(k,j);            R(i,j)=R(i,k);         end      end   end   k   D   Rend
182db08d9e3c6c8c9f049440edae120d.png

♡♡♡♡♡♡♡♡♡♡

ccda38e9b646030327ec95de77ff3596.png

扫码关注我

一起感悟科学魅力

cc88a2da7a7c3f944b8cd8f92de9226a.gif

点分享

98cd73feccaeb5af9ed68f3eca4853e5.gif

点点赞

ae4a25168f65e4445f7f9f255fb1c89b.gif

点在看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值