资源描述
一、主要功能
1.1程序的功能
在交通网络非常发达的今天,人们出差、旅游或做其他出行时,不仅关心节省交通费用,而且对里程和所需时间等问题也很感兴趣。对于这样一个人们关心的问题,可用一个图结构来表示交通网络系统,利用计算机建立一个交通咨询系统,能让旅客咨询从任一个城市顶点到达另外一个城市顶点之间的最短路径(里程)的问题,或者任意两个城市之间的最短路径问题。这样可以极大地方便旅客。
1.2输入输出的要求
在本程序里定义了一个EdgeType类,包括一个整型类型iDistance的成员;一个city结构体,包括了整型的Number和字符型的*Name成员;还定义了一个AdjMatrix类,包含了一些公有函数,如:int GetVexNum();//取得交通图的城市个数,void ShowRouteLength();//向用户显示路程长度,void Dijkstra(int v,int dist[],int path[]);//在图结构中求一个点到其他点的最短长度;也包含了四个私有成员数据:int iVexNum;//顶点数,即城市个数,int iEdgNum;//边数,即城市间的路线,City city[MaxValue];//图的顶点,即城市,EdgeType Route[MaxValue][MaxValue];//各边的权值,即路程。
从以上定义可以看出本程序的输入输出主要采用整型和字符串型的数据类型。
二、功能模块的划分
2.1存储交通信息网模块
在该系统中要求管理人员在旅客使用前先建立一个城市交通信息网,并保存以方便旅客的使用。
2.2查询一个城市到其他城市的路径模块图
交通咨询管理系统
一个城市到其他城市路径查询
迪克斯特拉算法求路径
显示旅客所咨询的信息
即路径长度
图(1)一个城市到另一个城市查询模块图 1
2.3查询任意两个城市的路径模块图
交通咨询管理系统
弗洛伊德算法求路径
任意两个城市
路径的查询
显示旅客咨询的信息
即路径长度
图(2)任意两个城市之间路径查询模块图
2.4整个系统程序模块图
交通咨询管理系统
管理员界面
用户界面
显示交通网
创建
城市
交通
网络
信息
网
咨询
一个
城市
到其
它城
市的
路径
问题
咨询
任意
两个
城市
之间
的路
径问
题
显示
城市
间的
路径
图(3)整个系统查询模块图
2
三、主要功能的实现
3.1.1城市交通咨询系统的流程图
输入
功能选择
管理员
用户
显示交通网
运行
输出结果
退出
开始
结束
Y
N
图(4)城市交通咨询系统的流程图
在本系统中设置了三个模块分别为:
管理员模块:这个模块包含了创建城市交通信息网,它是这个程序往下运行的前提。
用户模块:这个模块是属于用户的在已创建好的交通网上选择自己的需求。
显示交通网模块:这个模块是计算机的运算,运算出来的是用户想要的结果。
3
开始
路径初始化
选取不在S中且具有最短路径 的的城市U
城市U加入S中
修改不在S中的城市的距离
所有城市的最短路径是否都求出
输出结果
结束
Y
N
3.1.2一个城市到其它城市路径的查询
图(5)一个城市到其它城市路径的查询流程图
4
3.1.3任意两个城市之间路径的查询
路径初始化
最短路径是否经过其他城市
最短路径为所经过的城市之间的最短路径之和
任意两个城市之间的最短距离是否求出
输出结果
结束
开始
N
Y
Y
N
图(6)任意两个城市之间路径的查询
5
3.2.1一个城市到其它城市路径查询函数调用关系图
OnetoAnotherInfo()
函数
DijkstraShortDistance()函数
Dijkstra()
函数
输出结果
图(7)一个城市到其它城市路径查询函数调用关系图
3.2.2任意两个城市之间路径查询函数调用关系图
TwoCityInfo()
函数
FloydShortDistance()
函数
Floyd()
函数
输出结果
图(8)任意两个城市之间路径查询函数调用关系图
6
3.3.1 创建城市交通信息网模块算法代码
void AdjMatrix::CreateGraph()//构造交通图
{
City city1,city2;
int distance;
// char flag='y';
char *ch=new char(10);
cout<<"请输入想加入交通图的城市的数目:";
cin>>iVexNum;
cout<<"输入城市的信息:"<<endl;
for(int i=1;i<=iVexNum;i++)
{
cout<<"序号"<<i<<"的";
cout<<"城市名字:";
city[i].Name=new char;
cin>>city[i].Name;
city[i].Number=i;
}
cout<<"请输入路线的数目:"<<endl;
cin>>iEdgNum;
for(i=0;i<iEdgNum;i++)
{
cout<<"输入两个城市的信息:"<<endl;
cout<<"城市1名字:";
city1.Name=new char;
cin>>city1.Name;
city1.Number=GetCityNum(city1.Name);
cout<<"城市2名字:";
city2.Name=new char;
cin>>city2.Name;
city2.Number=GetCityNum(city2.Name);
cout<<"两地的路程为:"; 7
cin>>distance;
Route[city1.Number][city2.Number].iDistance=distance;
}
return;
}
3.3.2一个城市到其它城市路径查询模块的算法代码
void AdjMatrix::DijkstraShortDistance()//求一个城市到其他城市的最短路程
{
char *cityname=new char;
cout<<"请输入您要查询的城市:";
cin>>cityname;
int v0=GetCityNum(cityname);
int *dist=new int[iVexNum];
int *path=new int[iVexNum];
Dijkstra(v0,dist,path);
cout<<"从"<<cityname<<"城市到其他城市的最短路程为:"<<endl;
for(int i=1;i<=iVexNum;i++)
{
cout<<"到城市"<<GetCityName(i)
<<"的最短距离为"<<dist[i]<<"\n";
if(path[i]!=-1)
{
cout<<"路径为"<<GetCityName(i)<<"<-";
int x=path[i];
while(x!=v0)
{
cout<<GetCityName(x)<<"<-";
x=path[x];
}
cout<<cityname;
cout<<endl;
} 8
else cout<<endl;
}
}
3.3.3任意两个城市之间路径查询模块的算法代码
void AdjMatrix::FloydShortDistance()//求一个城市到其他城市的最短路程
{
char *cityname1=new char;
char *cityname2=new char;
int dist[MaxValue][MaxValue];
int path[MaxValue][MaxValue];
cout<<"请输入两个城市:";
cout<<"城市1:";
cin>>cityname1;
cout<<"城市2:";
cin>>cityname2;
int i= GetCityNum(cityname1);
int j= GetCityNum(cityname2);
Floyd( dist, path);
cout<<"城市"<<cityname1<<"到城市"<<cityname2
<<"的最短路径为"<<dist[i][j]<<endl;
if(path[i][j]!=-1)
{
cout<<"路径为:"<<cityname2<<"<-";
int x=path[i][j];
while(x!=i)
{
cout<<GetCityName(x)<<"<-";
x=path[i][x];
}
cout<<cityname1;
cout<<endl;
} 9
else cout<<endl;
}
四、程序调式
4.1测试数据
登录界面,即主界面
图(9)主界面
图(10)创建城市交通信息网界面
图(11)创建城市交通信息网界面
10
图(12)用户使用界面
图(13)一个城市到另一个城市的最短路径查询界面
图(14)任意两个城市之间路径的查询界面
图(15)退出系统界面 11
4.2程序调试中遇到的问题以及解决问题的方法
在本次程序设计中,遇到了不少的问题。首先就是怎么把图中的顶点和边转换成实际中的城市和城市之间距离信息的问题。为此我在本程序中写了两个函数,专门进行它们之间的转换。GetCityName()//返回城市的名字,GetCityNum()//通过城市名字取得城市的编号。
其次由于本程序是交通网,信息要求及时更新,所以我设置了管理员模块,管理员可以及时增加城市之间的信息。
第三,由于模块之间是相互嵌套调用的,所以用户在进行较高层次的使用后需要返回上一界面,因此就需要return函数。我在调试了几次后才最终确定return函数的位置。
第四,在计算路径时采取的迪克斯特拉算法及弗洛伊德算法,由于if语句的嵌套使用,会漏掉中括号,分号等,在调试中一一找出并进行纠正。
4.3课程设计过程心得体会
一周的数据结构课程设计很快就结束了,留给我们在这方面走的路却很远。本次实习,对我们来说可以说是一次小小的挑战。因为在理论实习中没有较好地把握,现在要完成一个较为复杂的程序编写,确实有点难度,但我们还是认真积极地完成了这次实习。
通过本次实验,我充分了解掌握了在图结构中最短路径的算法问题,并结合图的储存结构、迪杰斯特拉算法、费洛依德算法等解决了交通咨询系统的设计。源程序打出来后有多处错误,大小写错误、符号错误、遗漏等等,经反复检查调试后实验成功。在答辩时和老师讨论了我这个程序的不足及有待改进的地方,使我对自己的设计有了更好的把握及改进。感觉自己在编程方面更需要多多锻炼。
这次课程设计我相信在我们以后语言方面的学习中肯定会有莫大的帮助,我们必须认真思考,一步一个脚印,才可以达到我们预期的彼岸。
12
五、使用说明
本交通咨询系统设计界面友好,通俗易懂。
运行程序,系统会弹出提示界面,使用本系统前请先建立城市交通信息网,也即由管理者添加要加入到这个信息网的城市及城市之间的信息。添加完毕后会提示建立完毕,弹出选项框。如下图:
图(16)选项框
旅客选择2选项后,即进入用户界面,如下图:
图(17)用户界面
此时,用户可以根据自己的需要进行选择,接下来会提示旅客输入自己要查询的城市或者两个城市的名字。
图(18)提示界面
图(19)咨询界面
查询完毕后,选择0选项退出系统。
图(20)退出界面 13
整的来说,由于界面的友好性,相信使用的旅客都会感觉到其方便。
六、附件
#ifndef ADJMATRIX_H
#define ADJMATRIX_H
#include<vector>
#include<string>
using namespace std;
const int MaxValue=200;//城市路程最大值
struct EdgeType
{
int iDistance;//路程
};
struct City{
int Number;
char *Name;
};//城市结构体,包括城市名字以及城市在图结构中的编号
class AdjMatrix{
public:
AdjMatrix(int n);//构造函数
int GetVexNum();//取得交通图的城市个数
int GetEdgNum();//取得交通图的路线数目
int GetCityNum(char* cityname);//通过城市名字取得城市的编号
char* GetCityName(const int i);//通过序号取得城市的名字
void CreateGraph();//构造交通图
void ShowRouteLength();//向用户显示路程长度
void Dijkstra(int v,int dist[],int path[]);//在图结构中求一个点到其他点的最短长度
void DijkstraShortDistance();//实际中一个城市到其他城市的最短距离
void Floyd(int dist[MaxValue][MaxValue],int path[MaxValue][MaxValue]);//在图结构中两个点之间的最短长度
void FloydShortDistance();//实际中两个城市之间的最短距离
private:
int iVexNum;//顶点数,即城市个数 14
int iEdgNum;//边数,即城市间的路线
City city[MaxValue];//图的顶点,即城市
EdgeType Route[MaxValue][MaxValue];//各边的权值,即路程
};//交通网络图,有iVexNum个城市,城市之间有iEdgNum条路线
#endif
#include<iostream>
AdjMatrix::AdjMatrix(int n)//初始化有n个顶点的邻接矩阵
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(i==j)
{
Route[i][j].iDistance=0;
}
else
{
Route[i][j].iDistance=MaxValue;
}
}
iVexNum=iEdgNum=0;
}
int AdjMatrix::GetVexNum()//返回交通图的城市个数
{
return iVexNum;
}
int AdjMatrix::GetEdgNum()//城市间的路线
{
return iEdgNum;
}
char* AdjMatrix::GetCityName(const int i)//返回城市的名字
{ 15
return city[i].Name;
}
int AdjMatrix::GetCityNum(char* cityname)//通过城市名字取得城市的编号
{
for(int i=1;i<=iVexNum;i++)
{
if (strcmp(city[i].Name,cityname)==0)
return city[i].Number;
}
cout<<"您输入的城市有错误"<<endl;
return -1;
}
void AdjMatrix::CreateGraph()//构造交通图
{
City city1,city2;
int distance;
// char flag='y';
char *ch=new char(10);
cout<<"请输入想加入交通图的城市的数目:";
cin>>iVexNum;
cout<<"输入城市的信息:"<<endl;
for(int i=1;i<=iVexNum;i++)
{
cout<<"序号"<<i<<"的";
cout<<"城市名字:";
city[i].Name=new char;
cin>>city[i].Name;
city[i].Number=i;
}
cout<<"请输入路线的数目:"<<endl;
cin>>iEdgNum;
for(i=0;i<iEdgNum;i++) 16
{
cout<<"输入两个城市的信息:"<<endl;
cout<<"城市1名字:";
city1.Name=new char;
cin>>city1.Name;
city1.Number=GetCityNum(city1.Name);
cout<<"城市2名字:";
city2.Name=new char;
cin>>city2.Name;
city2.Number=GetCityNum(city2.Name);
cout<<"两地的路程为(单位为Km):";
cin>>distance;
Route[city1.Number][city2.Number].iDistance=distance;
}
return;
}
void AdjMatrix::ShowRouteLength()//向用户显示各个城市之间路程长度
{
cout<<"\t";
for(int i=1;i<=iVexNum;i++)
cout<<city[i].Name<<"\t";
cout<<endl;
for(i=1;i<=iVexNum;i++)
{
cout<<city[i].Name<<"\t";
for(int j=1;j<=iVexNum;j++)
cout<<Route[i][j].iDistance<<"\t";
cout<<endl;
}
}
void AdjMatrix::Dijkstra(int v0,int dist[],int path[])//迪克斯特拉算法,在一个图中求一个点到其他点的最短距离 17
{
int mindis;
int *s=new int(10);
int u;
for(int i=1;i<=iVexNum;i++)
{
dist[i]=Route[v0][i].iDistance;
s[i]=0;
if(i!=v0&&dist[i]<MaxValue)
path[i]=v0;
else path[i]=-1;
}
dist[v0]=0;
s[v0]=1;
for(i=1;i<iVexNum;i++)
{
mindis=MaxValue;
for(int j=1;j<=iVexNum;j++)
{
if(0==s[j]&&dist[j]<mindis)
{
u=j;
mindis=dist[j];
}
}
if(mindis==MaxValue) return;
s[u]=1;
for(int w=1;w<=iVexNum;w++)
if (0==s[w]&&Route[u][w].iDistance<MaxValue&&dist[u]+Route[u][w].iDistance<dist[w])
{
dist[w]=dist[u]+Route[u][w].iDistance; 18
path[w]=u;
}
}
}
void AdjMatrix::DijkstraShortDistance()//求一个城市到其他城市的最短路程
{
char *cityname=new char;
cout<<"请输入您要查询的城市:";
cin>>cityname;
int v0=GetCityNum(cityname);
int *dist=new int[iVexNum];
int *path=new int[iVexNum];
Dijkstra(v0,dist,path);
cout<<"从"<<cityname<<"城市到其他城市的最短路程为:"<<endl;
for(int i=1;i<=iVexNum;i++)
{
cout<<"到城市"<<GetCityName(i)
<<"的最短距离为"<<dist[i]<<"\n";
if(path[i]!=-1)
{
cout<<"路径为"<<GetCityName(i)<<"<-";
int x=path[i];
while(x!=v0)
{
cout<<GetCityName(x)<<"<-";
x=path[x];
}
cout<<cityname;
cout<<endl;
}
else cout<<endl;
} 19
}
void AdjMatrix::Floyd(int dist[MaxValue][MaxValue],int path[MaxValue][MaxValue])//在图中求一个源点到其他点的最短距离
{
int i,j,k;
for(i=1;i<=iVexNum;i++)
for(j=1;j<=iVexNum;j++)
{
dist[i][j]=Route[i][j].iDistance;
if(i!=j&&dist[i][j]!=MaxValue)
path[i][j]=i;
else
if(i==j) path[i][j]=0;
else path[i][j]=-1;
}
for(k=1;k<=iVexNum;k++)
for(i=1;i<=iVexNum;i++)
for(j=1;j<=iVexNum;j++)
{
if (dist[i][j]>(dist[i][k]+dist[k][j]))
{
dist[i][j]=dist[i][k]+dist[k][j];
path[i][j]=path[k][j];
}
}
}
void AdjMatrix::FloydShortDistance()//求一个城市到其他城市的最短路程
{
char *cityname1=new char;
char *cityname2=new char;
int dist[MaxValue][MaxValue];
int path[MaxValue][MaxValue]; 20
cout<<"请输入两个城市:";
cout<<"城市1:";
cin>>cityname1;
cout<<"城市2:";
cin>>cityname2;
int i= GetCityNum(cityname1);
int j= GetCityNum(cityname2);
Floyd( dist, path);
cout<<"城市"<<cityname1<<"到城市"<<cityname2
<<"的最短路径为"<<dist[i][j]<<endl;
if(path[i][j]!=-1)
{
cout<<"路径为:"<<cityname2<<"<-";
int x=path[i][j];
while(x!=i)
{
cout<<GetCityName(x)<<"<-";
x=path[i][x];
}
cout<<cityname1;
cout<<endl;
}
else cout<<endl;
}
AdjMatrix Gragh(20);
void Administrator() //管理员管理咨询系统的界面
{
int i;
cout<<endl;
cout<<"\t\t*****这里是管理员的界面,欢迎进入*****"<<endl;
cout<<"\t\t1=创建城市交通网络"<<endl
<<"\t\t0=返回上一级菜单"<<endl; 21
cout<<"请选择: ";
cin>>i;
while(i==1)
{
Gragh.CreateGraph();
cout<<"1=创建城市交通网络"<<endl
<<"0=返回上一级菜单"<<endl;
cout<<"请选择: ";
cin>>i;
}
return;
}
void OnetoAnotherInfo()//一个城市到其他城市信息的查询
{
int i;
cout<<endl;
cout<<"1=咨询一个城市到其他城市的最短路径"<<endl
<<"0=返回上一级菜单"<<endl;
cout<<"请选择: ";
cin>>i;
while(i==1)
{
Gragh.DijkstraShortDistance();
cout<<"1=咨询一个城市到其他城市的最短路径"<<endl
<<"0=返回上一级菜单"<<endl;
cout<<"请选择: ";
cin>>i;
}
return;
}
void TwoCityInfo()//两个城市之间的信息查询
{ 22
int i;
cout<<endl;
cout<<"1=咨询两个城市之间的最短路程"<<endl
<<"0=返回上一级菜单"<<endl;
cout<<"请选择: ";
cin>>i;
while(i==1)
{
Gragh.FloydShortDistance();
cout<<"1=咨询两个城市之间的最短路程"<<endl
<<"0=返回上一级菜单"<<endl;
cout<<"请选择: ";
cin>>i;
}
return;
}
int Passenger()//显示用户的界面
{
int i;
cout<<endl;
cout<<"*****这里是用户界面,欢迎进入*****"<<endl;
cout<<"1=咨询一个城市到其他城市的信息"<<endl
<<"2=咨询任意两个城市之间的信息"<<endl
<<"0=返回上一级菜单"<<endl;
cout<<"请选择: ";
cin>>i;
while(i!=0)
{
switch(i)
{
case 1:OnetoAnotherInfo();break;
case 2:TwoCityInfo();break; 23
}
cout<<"1=咨询一个城市到其他城市的信息"<<endl
<<"2=咨询任意两个城市之间的信息"<<endl
<<"0=返回上一级菜单"<<endl;
cout<<"请选择: ";
cin>>i;
}
return 1;
}
void ShowTrafficNet() //显示交通网络
{
int i;
cout<<endl;
cout<<"*****显示交通网路线的长度,欢迎进入*****"<<endl;
cout<<"1=显示路程长度"<<endl
<<"0=返回上一级菜单"<<endl;
cout<<"请选择: ";
cin>>i;
while(i==1)
{
Gragh.ShowRouteLength();//显示城市间的路程
cout<<"1=显示路程长度"<<endl
<<"0=返回上一级菜单"<<endl;
cout<<"请选择: ";
cin>>i;
}
return;
}
void main()//主函数
{
int i;
cout<<"\t\t**********您好!欢迎使用交通咨询系统*****"<<endl; 24
cout<<"\t\t**********请先创建城市交通网************"<<endl;
Administrator();
while(i!=0)
{
cout<<"现在请选择:"<<endl
<<"1=管理员"<<endl
<<"2=用户"<<endl
<<"3=显示交通网(用矩阵形式)"<<endl
<<"0=退出"<<endl;
cout<<"请选择: ";
cin >> i;
switch(i)
{
case 1:Administrator();break;//此处要显示管理员的界面
case 2:Passenger();break;//此处显示用户的界面
case 3:ShowTrafficNet();break;
}
}
return;
展开阅读全文