当前位置:文档之家› 实验四图的最短路径弗洛伊德算法实现

实验四图的最短路径弗洛伊德算法实现

数据结构与算法课程实验报告实验四:图的相关算法应用
姓名:王连平
班级:09信科2班
学号:I09630221
实验四图的相关算法应用
一、实验内容
求有向网络中任意两点之间的最短路。

二、实验目的
掌握图和网络的定义,掌握图的邻接矩阵、邻接表和十字链表等存储表示。

掌握图的深度和广度遍历算法,掌握求网络的最短路的标号法和floyd算法。

三、问题描述
对于下面一张若干个城市以及城市间距离的地图,从地图中所有可能的路径中求出任意两个城市间的最短距离及路径,给出任意两个城市间的最短距离值及途径的各个城市。

四、问题的实现
4.1数据结构的抽象数据类型定义和说明
1)
typedef struct ArcCell{//储存弧信息
int Distance;
ArcCell *info;//此项用来保存弧信息,,在本实验中没有相关信息要保存
}ArcCell,AdjMatrix[ MAX_VERTEX_NUM][ MAX_VERTEX_NUM];
typedef struct{//储存顶点信息
string vexs[ MAX_VERTEX_NUM];//顶点向量
AdjMatrix arcs;//邻接矩阵
int vexnum , arcnum;//图的当前顶点数和弧数
}MGraph;
顶点信息和弧信息都是用来建立一个有向网G
2)
d[v][w];//G中各对顶点的带权长度
若P[v][w][u]为TRUE,则u是从v到w当前求得最短路径上的顶点
4.2主要的实现思路
首先通过一个函数(CreateDN)建立图的邻接矩阵储存方式,一次输入某条弧的起点,终点,和权值。

通过调用Locate函数来找到该弧在邻接矩阵中的相应位置。

其次运用弗洛伊德算法来求各定点的最短路劲,具体思路为:如果从v到w有弧,则存在一条长度为arcs[v][w]的路径,该路径不一定是最短路径。

考虑路径(v,u,w)是否存在,若存在,比较(v,w)和(v,u,w)的长度,取较短者为从v到w的中间点序号不大于0的最短路径。

以此类推,每次增加一个点,从而求出任意两点间的最短路径。

这样,经过n次比较后,所求得的必为从v到w的最短路径。

按此方法,可以同时求得任意两点间的最短路径。

五、主要源程序代码(包含程序备注)
#include<iostream>
#include<string>
using namespace std;
#define INfinity 10000//最大值
# define MAX_VERTEX_NUM 10//最大顶点数
typedef struct ArcCell{//储存弧信息
int Distance;
ArcCell *info;
}ArcCell,AdjMatrix[ MAX_VERTEX_NUM][ MAX_VERTEX_NUM];
typedef struct{//储存顶点信息
string vexs[ MAX_VERTEX_NUM];//顶点向量
AdjMatrix arcs;//邻接矩阵
int vexnum , arcnum;//图的当前顶点数和弧数
}MGraph;
int Locate(MGraph &G,string v)
{ int a=0;
for (int i=0;i<G.vexnum;i++)
{
if( G.vexs[i]==v) {
a=i;
break;}
}
return a;
}
void CreateDN(MGraph &G)//采用邻接矩阵表示法,构造有向图G
{ string v1,v2;
cout<<"请依次输入图的顶点数和弧数"<<endl;
cin>>G.vexnum>>G.arcnum;
for (int i=0;i<G.vexnum;i++)
{ cout<<"请按顺序输入地点"<<endl;
cin>>G.vexs[i];
}
for (int i=0;i<G.vexnum;i++)//初始化邻接矩阵;
{ for (int j=0;j<G.vexnum;j++) G.arcs[i][j].Distance=INfinity;}
for (int k=0;k<G.arcnum;k++){
cout<<"请输入某条路径的初始地点V1,终点V2及他们之间的距离W"<<endl; cin>>v1>>v2>>w;
int i=Locate(G,v1);
int j=Locate(G,v2);
G.arcs[i][j].Distance=w;
}
}
void Floyd(MGraph &G)
{ int P[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int d[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
for (int v=0;v<G.vexnum;v++)
{ for (int w=0;w<G.vexnum;w++)
{ d[v][w]=G.arcs[v][w].Distance;
for (int u=0;u<G.vexnum;u++)
{ P[v][w][u]=0;
if (d[v][w]<INfinity)//从v到w有直接路径
{P[v][w][v]=1;P[v][w][w]=1; }
}
}
}
for (int u=0;u<G.vexnum;u++)
{for (int v=0;v<G.vexnum;v++)
{for (int w=0;w<G.vexnum;w++)
{ if (d[v][u]+d[u][w]<d[v][w])//从v经u到w的一条路径更短
{
d[v][w]=d[v][u]+d[u][w];
for (int i=0;i<G.vexnum;i++)
{P[v][w][i]=P[v][u][i]||P[u][w][i];}
}
}
}
}
for (int v=0;v<G.vexnum;v++)
{for (int w=0;w<G.vexnum;w++)
{cout <<"从"<<G.vexs[v]<<"到"<<G.vexs[w]<<"的最短路径为:"<<d[v][w]<<endl;
cout <<"途径城市为:";
for (int u=0;u<G.vexnum;u++)
{ if (P[v][w][u]==1)//P[v][w][u]为,说明u为v到w的最短路劲中的一个顶点
{cout <<G.vexs[u];}
}
cout<<""<<endl;
}
}
}
}
void main()
{MGraph *G;
G=new MGraph;
CreateDN(*G);
Floyd(*G);
}
六、总结
通过本次试验,我对于图的定义及其邻接矩阵储存方式有了进一步的了解。

同时对Flyd算法也有了更深的认识。

特别是用这种方法求求任意两点最短路径的过程比用迪杰斯特算法算n次的形式上更加简单,
时间复杂度为()3n O
,是一个简便的算法。

当然在这次实验没用到图的邻接表和十字链表表示方法,所以
在课后需要花更多的时间去熟悉这两种储存方式,同时也要去了解求网络的最短路的标号法。

相关主题