Floyd算法:
一、问题描述:
从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从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算法求解下图各个顶点的最短距离。写出Floyd算法的伪代码和给出距离矩阵(顶点之间的最短距离矩阵);
二、算法核心步骤(伪代码)及图解:
- 将图转化为邻接矩阵(主对角线,也就是自身到自身,我们规定距离为0,不可达为无穷大);
- 再创建一个二维数组P路径数组,用于存放任意一对顶点之间的最短路径。(初始还未开始查找,默认-1)
- 列举所有的路径,转化成二元数组;
- 依次选择编号为1,2,3,4的点为中间点,(以1为例);判断 (D[ i ][ 1 ]+D[ 1 ][ j ] ) < D[ i ][ j ] 如果表达式为真,更新D[ i ] [ j ]的值为D[ i ] [ 1 ] + D[ 1 ] [ j ],P[ i ] [ j ]的值为点1(即设置i到j要经过1点中转);
- 根据最终结果,就可以知道任意2点的最短距离和路径
图解:
三、代码实现:
#include <stdio.h>
#define INFINITY 65535
typedef int VertexType;
typedef int EdgeType;
typedef struct //图的邻接矩阵存储结构
{
VertexType vexs[4]; //顶点向量
EdgeType edges[4][4]; //邻接矩阵
int vexnum,arcnum; //顶点数和边数
}MGraph;
void CreateGraph(MGraph *G)
{
int i,j,k,weight;
int a,b;
printf("请输入顶点数和边数:");
scanf("%d,%d",&(G->vexnum),&(G->arcnum));
printf("请输入顶点名称:");
for(i=0;i<G->vexnum;i++)
{
getchar();
scanf("%d",&(G->vexs[i]));
}
for(i=0;i<G->vexnum;i++)
for(j=0;j<G->vexnum;j++)
if(i==j)
{
G->edges[i][j]=0;
}
else
G->edges[i][j]=INFINITY;
for(k=0;k<G->arcnum;k++)
{
printf("请输入第%d条边的两个顶点名称:",k+1);
scanf("%d,%d",&a,&b);
for(i=0;a!=G->vexs[i];i++);
for(j=0;b!=G->vexs[j];j++);