全局最短路径之弗洛伊德算法
来源:互联网 发布:中国基尼系数知乎 编辑:程序博客网 时间:2024/05/16 05:01
Floyd(弗洛伊德)算法
该算法是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权(但不可存在负权回路)的最短路径问题,同时也被用于计算有向图的传递闭包。
时间复杂度为 O(N^3)
空间复杂度为 O(N^2)
Floyd算法蕴涵了动态规划的思想,
简单说:从任意节点i到任意节点j的最短路径存在两种可能
- 直接从i到j
- i经过若干个节点k到j
所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。
Floyd算法适用于APSP(All Pairs Shortest Paths,多源最短路径),是一种动态规划算法,稠密图效果最佳。此算法简单有效,由于三重循环结构紧凑,对于稠密图,效率要高于Dijkstra算法
优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单。
缺点:时间复杂度比较高,不适合计算大量数据。
算法代码如下:
void Floyd(AdjMatrix *G){ int A[MaxVertices][MaxVertices],path[MaxVertices][MaxVertices]; int i,j,k; //初始化 for (i=0;i<G->numV;i++) { for (j=0;j<G->numV;j++) { A[i][j]=G->Edge[i][j]; path[i][j]=-1; } }//三重循环,floyd算法核心 for (k=0;k<G->numV;k++) { for (i=0;i<G->numV;i++) { for (j=0;j<G->numV;j++) { if (A[i][j]>A[i][k]+A[k][j]) { A[i][j]=A[i][k]+A[k][j]; path[i][j]=k; } } } } Dispath(A,path,G->numV);//输出函数}
输出函数包括两部分
void Ppath(int path[][MaxVertices],int i,int j){ int k; k=path[i][j]; if (k==-1) { return; } Ppath(path,i,k); printf("%d->",k); Ppath(path,k,j);}void Dispath(int A[][MaxVertices],int path[][MaxVertices],int n){ int i,j; for (i=0;i<n;i++) { for (j=0;j<n;j++) { if (A[i][j]==INF) { if (i!=j) { printf("从%d到%d没有路径\n",i,j); } } else { printf(" 从%d到%d的最短路径长度为:%d ",i,j,A[i][j]); printf("路径:%d->",i); Ppath(path,i,j);//两点i,j之间还有其他中继结点,则循环套用次函数 printf("%d\n",j); } } }}
具体代码如下:
#include<stdio.h>#include<stdlib.h>#define MaxVertices 100 //假设包含100个顶点#define MaxWeight 32767 //不邻接时为32767,但输出时用 "∞"#define MAXV 10#define INF 32767typedef struct{ //包含权的邻接矩阵的的定义 char Vertices[MaxVertices]; //顶点信息的数组 int Edge[MaxVertices][MaxVertices]; //边的权信息的数组 int numV; //当前的顶点数 int numE; //当前的边数}AdjMatrix;void CreateGraph(AdjMatrix *G) //图的生成函数{ int n,e,vi,vj,w,i,j; printf("请输入图的顶点数和边数(以空格分隔):"); scanf("%d%d",&n,&e); G->numV=n;G->numE=e; for(i=0;i<n;i++) //图的初始化 for(j=0;j<n;j++) { if(i==j) G->Edge[i][j]=0; else G->Edge[i][j]=32767; } for(i=0;i<n;i++) for(i=0;i<G->numV;i++) //将顶点存入数组中 { printf("请输入第%d个顶点的信息(整型):",i+1); // G->adjlist[i].vertex=getchar(); scanf(" %c",&G->Vertices[i]); } printf("\n"); for(i=0;i<G->numE;i++) { printf("请输入边的信息i,j,w(以空格分隔):"); scanf("%d%d%d",&vi,&vj,&w); //若为不带权值的图,则w输入1 //若为带权值的图,则w输入对应权值 G->Edge[vi-1][vj-1]=w;//① G->Edge[vj-1][vi-1]=w;//② //无向图具有对称性的规律,通过①②实现 //有向图不具备此性质,所以只需要① }}void DispGraph(AdjMatrix G) //输出邻接矩阵的信息{ int i,j; printf("\n输出顶点的信息(整型):\n"); for(i=0;i<G.numV;i++) printf("%8c",G.Vertices[i]); printf("\n输出邻接矩阵:\n"); printf("\t"); for(i=0;i<G.numV;i++) printf("%8c",G.Vertices[i]); for(i=0;i<G.numV;i++) { printf("\n%8d",i+1); for(j=0;j<G.numV;j++) { if(G.Edge[i][j]==32767) //两点之间无连接时权值为默认的32767,但输出时为了方便输出 "∞" printf("%8s", "∞"); else printf("%8d",G.Edge[i][j]); } printf("\n"); }}void Ppath(int path[][MaxVertices],int i,int j){ int k; k=path[i][j]; if (k==-1) { return; } Ppath(path,i,k); printf("%d->",k); Ppath(path,k,j);}void Dispath(int A[][MaxVertices],int path[][MaxVertices],int n){ int i,j; for (i=0;i<n;i++) { for (j=0;j<n;j++) { if (A[i][j]==INF) { if (i!=j) { printf("从%d到%d没有路径\n",i,j); } } else { printf(" 从%d到%d的最短路径长度为:%d ",i,j,A[i][j]); printf("路径:%d->",i); Ppath(path,i,j);//两点i,j之间还有其他中继结点,则循环套用次函数 printf("%d\n",j); } } }}void Floyd(AdjMatrix *G){ int A[MaxVertices][MaxVertices],path[MaxVertices][MaxVertices]; int i,j,k; //初始化 for (i=0;i<G->numV;i++) { for (j=0;j<G->numV;j++) { A[i][j]=G->Edge[i][j]; path[i][j]=-1; } }//三重循环,floyd算法核心 for (k=0;k<G->numV;k++) { for (i=0;i<G->numV;i++) { for (j=0;j<G->numV;j++) { if (A[i][j]>A[i][k]+A[k][j]) { A[i][j]=A[i][k]+A[k][j]; path[i][j]=k; } } } } Dispath(A,path,G->numV);//输出函数}int main(){ AdjMatrix G; freopen("1.txt","r",stdin); CreateGraph(&G); Floyd(&G); DispGraph(G);}
注:由于测试输入数据较多,程序可以采用文件输入
5 7
1
2
3
4
5
1 2 2
1 3 4
1 5 2
2 3 1
2 4 6
3 4 2
4 5 3
阅读全文
0 0
- 全局最短路径之弗洛伊德算法
- 最短路径之弗洛伊德算法(Floyd)
- 最短路径之Floyd(弗洛伊德)算法
- 最短路径之弗洛伊德算法
- MPI之弗洛伊德最短路径算法
- 最短路径之弗洛伊德算法
- 弗洛伊德最短路径算法
- 弗洛伊德算法--最短路径
- 最短路径-弗洛伊德算法
- 弗洛伊德最短路径算法
- 最短路径(弗洛伊德算法)
- 最短路径--弗洛伊德算法
- 最短路径:弗洛伊德算法
- 弗洛伊德最短路径算法
- 弗洛伊德最短路径算法
- 最短路径---弗洛伊德算法
- 最短路径(弗洛伊德算法)
- 算法:最短路径之弗洛伊德(Floyd)算法
- FCC-----------Missing letters
- ubuntu下配置网络(IP、网关、DNS)
- android 六边形蜂巢布局控件
- JVM笔记
- Linux SUID位的作用
- 全局最短路径之弗洛伊德算法
- Ubuntu14.04-server下安装WDCP
- PropertyResolver
- 通过JDBC连接Hive以及常见异常处理方式
- 数据库知识点
- android知识点
- 字符数组的赋值
- Halcon + VS2013 C#配置
- windows计划任务设置每小时执行一次