携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第17天,点击查看活动详情
介绍
和 Dijkstra 算法一样,弗洛伊德(Floyd)算法 也是一种用于寻找给定的加权图中顶点间最短路径的算法。该算法名称以创始人之一、1978 年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名
弗洛伊德算法(Floyd)计算图中 各个顶点之间 的最短路径,比如:先从 A 出发到各个点的最短路径,再从 B 出发,直到所有节点距离各个点的路径都会计算出来。而迪杰斯特拉算法用于计算图中 某一个顶点到其他顶点的最短路径。
弗洛伊德算法 VS 迪杰斯特拉算法:
- 迪杰斯特拉算法通过选定的被访问顶点,求出从出发访问顶点到其他顶点的最短路径;
- 弗洛伊德算法中每一个顶点都是出发访问点,所以需要将每一个顶点看做被访问顶点,求出从每一个顶点到其他顶点的最短路径。
核心思想
设:
- 顶点 vi 到顶点 vk 的最短路径已知为Lik,
- 顶点 vk 到 vj 的最短路径已知为 Lkj
- 顶点 vi 到 vj 的路径为 Lij
则 vi 到 vj 的最短路径为:min((Lik+Lkj),Lij),vk 的取值为图中所有顶点,则可获得 vi 到 vj 的最短路径(则:假设三个点(不一定是具体的是 3 个点),一个直达,一个间接到达,算哪个路径最短)
至于 vi 到 vk 的最短路径 Lik 或者 vk 到 vj 的最短路径 Lkj,是以同样的方式获得。
path矩阵递归实现完整路线
博文是主要实现王道机构学长所说的==path矩阵递归找到完整路径==,也是一个很简单递归,主要是将起点和终点之间的其他连接结点找到,所以用递归类似于二分,找到一个中间结点之后再对左右分别进行递归。
本文提供了完整的实现代码,以及两组实验数据用例。(仅初学Floyd算法使用,没有提供优化思路)
void Floyd(){
for(int k=0;k<n;k++){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(A[i][j]>A[i][k]+A[k][j]){
A[i][j]=A[i][k]+A[k][j];
path[i][j]=k;
}
}
}
//printData(A);
}
}
void findpath(int st,int ed){
if(A[st][ed]<INF && path[st][ed]==(-1)){
printf("->>%d",ed);
}
else{
int mid = path[st][ed];
findpath(st,mid);
findpath(mid,ed);
}
}
void find_FloydPath(int st,int ed){
printf("%d点到%d点的最短路径为:%d",st,ed,st);
findpath(st,ed);
}
实验用例1
/*
3 5
0 1 6
0 2 13
1 0 10
1 2 4
2 0 5
*/
实验用例2
/*
5 7
0 2 1
0 4 10
1 4 5
1 3 1
2 1 1
2 4 7
3 4 1