最短路径,弗洛伊德(Floyd)算法及C/C++代码实现
创作时间:
作者:
@小白创作中心
最短路径,弗洛伊德(Floyd)算法及C/C++代码实现
引用
1
来源
1.
https://www.dotcpp.com/course/153
1. 算法简介
弗洛伊德算法与迪杰斯特拉算法是公认的最著名的两种最短路径求解算法,接下来介绍弗洛伊德算法,弗洛伊德算法的思路是:首先初始化距离矩阵,然后从第一个点开始逐渐更新矩阵点值。d[i][j]表示从i点到j点的距离。第k次更新时,判断d[i][k]+d[k][j]与d[i][j]的大小,如果前者小,则更新这个值,否则不变。
这个算法的核心点在于去往每一个点我们所要尽力的每一个点的记录
(参考图,试着拿本图进行一次构建吧)
2.算法实现:
通过一个图的权值矩阵求出它的每两点间的最短距离矩阵。
从图的带权邻接矩阵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来记录两点间的最短路径。
采用松弛技术(松弛操作),对在i和j之间的所有其他点进行一次松弛。所以时间复杂度为O(n^3);
状态转移方程
其状态转移方程如下: map[i,j]:=min{map[i,k]+map[k,j],map[i,j]};
map[i,j]表示i到j的最短距离,K是穷举i,j的断点,map[n,n]初值应该为0或者自定义的特殊意义的点
3. 代码实现
参考代码,简化了输入操作直接赋值。
#include <stdio.h>
#include <stdlib.h>
#define MAXVEX 9
#define INFINITY 65535
struct MGraph {
int numVertexes;
int *vex;
int arc[MAXVEX][MAXVEX];
};
typedef int PathMatrix[MAXVEX][MAXVEX];
typedef int ShortPathTable[MAXVEX][MAXVEX];
void ShortestPath_Floyd(MGraph *G,PathMatrix *P,ShortPathTable *D) {
int v,w,k;
//初始化
for(v=0; v<G->numVertexes; ++v) {
for(w=0; w<G->numVertexes; ++w) {
(*D)[v][w]=G->arc[v][w];
(*P)[v][w]=w;
}
}
for(k=0; k<G->numVertexes; ++k) {
for(v=0; v<G->numVertexes; ++v) {
for(w=0; w<G->numVertexes; ++w) {
if( (*D)[v][w]>(*D)[v][k]+(*D)[k][w] ) { // (v到w的距离) VS (v到k的距离+k到w的距离)
(*D)[v][w]=(*D)[v][k]+(*D)[k][w];
(*P)[v][w]=(*P)[v][k]; //若从v出发,要去w,则先要从v去到k,“再作下一步打算(下一步即(*P)[k][w])”
}
}
}
}
}
void main() {
MGraph *my_g=(struct MGraph*)malloc(sizeof(struct MGraph));
int i,j;
int t=0;
int v0=0;
int vv=8;
my_g->numVertexes=MAXVEX;
my_g->vex=(int*)malloc(sizeof(char)*my_g->numVertexes);
if(!my_g->vex) return;
for(i=0; i<my_g->numVertexes; ++i) //一维数组(图中各结点)初始化{0,1,2,3,4,5,6,7,8}
my_g->vex[i]=i++;
for(i=0; i<my_g->numVertexes; ++i)
for(j=0; j<my_g->numVertexes; ++j)
my_g->arc[i][j]=INFINITY;
// 无向图的权值二维数组为对称矩阵
my_g->arc[0][1]=1;
my_g->arc[0][2]=5;
my_g->arc[1][2]=3;
my_g->arc[1][3]=7;
my_g->arc[1][4]=5;
my_g->arc[2][4]=1;
my_g->arc[2][5]=7;
my_g->arc[3][4]=2;
my_g->arc[3][6]=3;
my_g->arc[4][5]=3;
my_g->arc[4][6]=6;
my_g->arc[4][7]=9;
my_g->arc[5][7]=5;
my_g->arc[6][7]=2;
my_g->arc[6][8]=7;
my_g->arc[7][8]=4;
for(i=0; i<my_g->numVertexes; ++i)
for(j=0; j<=i; ++j) {
if(i==j) {
my_g->arc[i][j]=0;
continue;
}
my_g->arc[i][j]=my_g->arc[j][i];
}
for(i=0; i<my_g->numVertexes; ++i) { //二维数组表示图中各结点间连接边的weight
for(j=0; j<my_g->numVertexes; ++j)
printf("%5d ",my_g->arc[i][j]);
printf("\n");
}
printf("\n\n");
PathMatrix D;
ShortPathTable P;
ShortestPath_Floyd(my_g,&P,&D);
for(i=0; i<MAXVEX; ++i) { //二维数组表示图中各结点间连接边的weight
for(j=0; j<MAXVEX; ++j)
printf("%5d ",P[i][j]);
printf("\n");
}
printf("\n\n");
free(my_g->vex);
}
热门推荐
PU皮衣的保养与清洗:洗前必看的五个关键步骤!
张衡传:一位古代科学家的传奇人生
扩散模型详解:从理论到实践
锐捷网管交换机DHCPv6服务器动态分配IPv6地址配置详解
左心房肥大如何治疗
姜文新片《英雄出少年》官宣2025上映,赵本山葛优助阵演员阵容豪华
手机信号屏蔽器:工作原理、应用场景与选购指南
老师与家长冲突,谁对谁错?
烫伤疤痕用什么药膏才能去除干净
房子坐北朝南的优势及判断方法
新加坡入籍条件详解:居住时长与社区贡献如何计算
案例拆解:张琦那个操盘手是怎么做出这全网一个亿的粉丝IP的?
什么是 GitHub Wiki 以及如何使用它?
水在生态环境中所扮演的重要角色
冷冻的饺子是冷水下锅还是热水下锅?煮冷冻饺子的秘诀大揭秘!
扁平化网页设计的魅力与趋势探索:打造简约而不简单的用户体验
美国学校如何运用人工智能提升教育质量
关于掉头的3个疑问,今天一次讲明白
Memory.dmp文件是什么?如何分析解决系统崩溃问题?
边牧智商相当于人几岁
北京理工大学排名怎么样?“理工第一校”,科研实力不容小觑!
蓝莓肥料用的对,根壮树旺产量高!
发动机故障率最高的三款车,普通人最好别买,油耗高,你怎么看
湿疹忌吃什么
天策上将:中国古代最尊贵的武官职位
如何解决丰田雷凌自燃问题?这些解决方法存在哪些挑战?
数字孪生技术助力智慧医院设备维护与管理创新
如何在Windows系统中设置全局代理?
电脑无法连接WiFi无线网络?原因与解决方法大揭秘!
软件工程考公务员有哪些岗位?附2024年内蒙古录取分数线