如何解决弗洛伊德算法写的最短路径有什么问题?
我使用 Floyd 算法写出最短路径。数据是这个图,但是得到的path[0][7]是5而不是4,为什么?
D中0到9的路径权重没有错,但是path[0][7]错了
Floyd 算法:
bool Floyd( MGraph Graph,WeightType D[][MaxVertexnum],Vertex path[][MaxVertexnum] )
{
//Initialize path[] and distance
for( int i = 0; i < Graph->Nv; i++ ){
for( int j = 0; j < Graph->Nv; j++ ){
D[i][j] = Graph->G[i][j];
path[i][j] = -1;
}
}
//Floyd algorithm
for( int k = 0; k < Graph->Nv; k++ ){
for( int i = 0; i < Graph->Nv; i++ ){
for( int j = 0; j < Graph->Nv; j++ ){
if( D[i][k] + D[k][j] < D[i][j] ){
D[i][j] = D[i][k] + D[k][j];
if( i == j && D[i][j] < 0 )
return false;
path[i][j] = k;
}
}
}
}
return true;
}
完整代码:
#include<stdlib.h>
#include<stdio.h>
#include<stdbool.h>
#define MaxVertexnum 100 //Maximum of 100 vertices
#define INFINITY 65535 //Define infinity
typedef int Vertex;
typedef int WeightType;
typedef int DataType;
// Vertex
struct Gnode{
int Nv; //the number of vertex
int Ne; //the number of edge
WeightType G[MaxVertexnum][MaxVertexnum]; //Adjacency matrix
DataType Data[MaxVertexnum]; //Vertex data
};
typedef struct Gnode *MGraph;
// Edge
struct Enode{
Vertex V1,V2; //Directed edges <V1,V2>
WeightType Weight; //Weight
};
typedef struct Enode *Edge;
// Initialize an edgeless graph with Vertexnum vertices
MGraph CreatGraph( int Vertexnum )
{
Vertex V,W;
MGraph Graph;
Graph = (MGraph)malloc(sizeof(struct Gnode));
Graph->Nv = Vertexnum;
Graph->Ne = 0;
for( V = 0; V < Graph->Nv; V++ ){
for( W = 0; W < Graph->Nv; W++ ){
Graph->G[V][W] = INFINITY;
}
}
return Graph;
}
void InsertEdge( MGraph Graph,Edge E )
{
Graph->G[E->V1][E->V2] = E->Weight;
Graph->G[E->V2][E->V1] = E->Weight;
}
MGraph BuildGraph()
{
MGraph Graph;
Edge E;
Vertex V;
int Nv;
//Initialize the Graph
printf("Enter the number of vertices:");
scanf("%d",&Nv);
Graph = CreatGraph( Nv );
//Input Edge
printf("\nEnter the number of edges:");
scanf("%d",&(Graph->Ne));
if( Graph->Ne != 0 ){
E = (Edge)malloc(sizeof(struct Enode));
for( int i = 0; i < Graph->Ne; i++ ){
scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);
InsertEdge( Graph,E );
}
}
//vertex data
printf("\nEnter vertex data:\n");
for( V = 0; V < Graph->Nv; V++ ){
scanf(" %d",&(Graph->Data[V]));
}
return Graph;
}
bool Floyd( MGraph Graph,Vertex path[][MaxVertexnum] )
{
//Initialize path[] and distance
for( int i = 0; i < Graph->Nv; i++ ){
for( int j = 0; j < Graph->Nv; j++ ){
D[i][j] = Graph->G[i][j];
path[i][j] = -1;
}
}
//Floyd algorithm
for( int k = 0; k < Graph->Nv; k++ ){
for( int i = 0; i < Graph->Nv; i++ ){
for( int j = 0; j < Graph->Nv; j++ ){
if( D[i][k] + D[k][j] < D[i][j] ){
D[i][j] = D[i][k] + D[k][j];
if( i == j && D[i][j] < 0 )
return false;
path[i][j] = k;
}
}
}
}
return true;
}
int main()
{
MGraph Graph;
Graph = BuildGraph();
printf("\nThis is the adjacency matrix:\n");
for( int i = 0; i < Graph->Nv; i++ ){
for( int j = 0; j < Graph->Nv; j++ ){
printf("%-8d",Graph->G[i][j]);
}
printf("\n");
}
//Shortest path
int D[MaxVertexnum][MaxVertexnum];
int path[MaxVertexnum][MaxVertexnum];
Floyd( Graph,D,path );
Vertex V1,V2;
printf("starting point:");
scanf("%d",&V1);
printf("End point:");
scanf("%d",&V2);
int v1,v2;
v1 = V1;
v2 = V2;
while( path[v1][v2] != -1 ){
printf("%d<-",Graph->Data[path[v1][v2]] );
v2 = path[v1][v2];
}
return 0;
}
测试数据:
10
17
0 1 2
0 3 5
1 2 5
1 3 2
2 4 8
2 5 4
3 5 4
3 6 2
4 5 2
4 7 5
5 6 3
5 7 9
5 8 6
6 8 7
7 8 3
7 9 4
8 9 8
0
1
2
3
4
5
6
7
8
9
解决方法
path[i][j] = k;
中的 Floyd
行没有考虑到从 k
到 j
的最短路径(到目前为止)可能是通过一个中间节点这一事实。将该行更改为 path[i][j] = path[k][j] == -1 ? k : path[k][j];
可以解决该问题。
我还建议将节点到自身的距离设置为 0。这可以通过将行 D[i][j] = Graph->G[i][j];
更改为 D[i][j] = i == j ? 0 : Graph->G[i][j];
来实现。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。