校园最短路径问题的研究与实现.docx
《校园最短路径问题的研究与实现.docx》由会员分享,可在线阅读,更多相关《校园最短路径问题的研究与实现.docx(34页珍藏版)》请在冰豆网上搜索。
校园最短路径问题的研究与实现
校园最短路径问题的研究与实现
学生姓名:
指导老师:
摘要本课程设计主要解决求的校园任意地点间最短路径的问题。
在本程序中,对于任意一个起点,如果不确定具体的终点,则以表格形式输出从起点到其他各地点的最短路径长度以及途经哪些地点;如果用户确定终点,则只输出从起点到具体地点的最短路径长度以及途经哪些地点。
同时还能实现对校园路径图的修改功能,如顶点以及边的增删、边上权值的修改等。
在程序设计中,采用VisualC++程序设计语言,以及MicrosoftVisualC++6.0开发平台进行开发实现。
关键词校园最短路径;起点;终点;路径图修改;C++
目录
1.引言………………………………………………………………………………3
1.1课程设计目的………………………………………………………………………………3
1.2概要设计……………………………………………………………………………………3
2.详细设计…………………………………………………………………………5
2.1功能流程图…………………………………………………………………………………5
2.2类的定义……………………………………………………………………………………5
2.3功能函数实现………………………………………………………………………………7
2.4算法分析…………………………………………………………………………………..14
2.5程序调试…………………………………………………………………………………..14
3.测试运行………………………………………………………………………..16
3.1开始界面测试……………………………………………………………………………..16
3.2输出顶点信息功能测试…………………………………………………………………..16
3.3输出边信息功能测试……………………………………………………………………..16
3.4修改功能测试……………………………………………………………………………..17
3.5求最短路径功能测试……………………………………………………………………..17
3.6删除顶点功能测试………………………………………………………………………..18
3.7插入顶点功能测试………………………………………………………………………..19
3.8删除边功能测试…………………………………………………………………………..19
3.9插入边功能测试…………………………………………………………………………..20
3.10退出程序测试……………………………………………………………………………21
4.结束语…………………………………………………………………………..23
参考文献………………………………………………………………………….24
附录:
程序清单………………………………………………………………….25
1引言
本课程设计主要解决校园最短路径的求取,校园中的各具体地点作为顶点,各顶点间的路径作为边,可实现对顶点及边的信息进行添加、删除及修改等功能,可显示各顶点及边的信息,可求出每一对顶点间的最短路径和单源点最短路径[1]。
1.1课程设计目的
1.了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;
2.初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;
3.提高综合运用所学的理论知识和方法独立分析和解决问题的能力;
4.训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学工作方法和作风[2]。
1.2概要设计
1.问题描述
图的最短路径问题是指从指定的某一点v开始,求得从该地点到图中其它各地点的最短路径。
并且给出求得的最短路径的长度及途径的地点。
除了完成最短路径的求解外,还能对该图进行修改,如顶点以及边的增删、边上权值的修改等。
校园最短路径问题中的数据元素有:
(1)顶点数
(2)边数
(3)边的长度
2.功能需求
要求完成以下功能:
(1)输出顶点信息:
将校园内各位置输出。
(2)输出边的信息:
将校园内每两个位置(若两个位置之间有直接路径)的距离输出。
(3)修改:
修改两个位置(若两个位置之间有直接路径)的距离,并重新输出每两个位置(若两个位置之间有直接路径)的距离;
(4)求最短路径:
输出给定两点之间的最短路径的长度及途经的地点或输出任意一点与其他各点的最短路径。
(5)删除:
删除任意一条边。
(6)插入:
插入任意一条边。
3.实现要点
(1)对图的创建采用邻接矩阵的存储结构,而且对图的操作设计成了模板类。
为了便于处理,对于图中的每一个顶点和每一条边均设置了初值。
(2)为了便于访问,用户可以先输出所有的地点及距离。
(3)用户可以随意修改任意两点之间的距离。
(4)用户可以任意增加及删除边。
(5)当用户操作错误时,系统会出现出错提示。
4.方案设计
本程序采用Dijkstra算法实现最短路径的求解,因此,校园分布图采用邻接矩阵进行存储。
在主程序中以菜单方式给出提示,进入各功能要求用户输入现在的位置,以及是否有确定的重点。
主程序中对该图进行初始化,有一定的实验数据[3]。
2详细设计
2.1功能流程图
图2.1系统功能流程图
2.2类的定义
为构建图及最短路径建立了图的类,其类定义如下:
constintMaxSize=12;//图中最多顶点个数
template
classGraph
{
public:
Graph(int*a,T*v,intn);//构造函数,初始化具有n个顶点的图
~Graph(){}//析构函数
voidDijkstra(intv,intendv);//最小距离
voidPutOutVexInfo();//取顶点信息
voidPutOutArcInfo();//输出路径
voidSetArc(intv1,intv2,intarclength);//修改路径
voidDeleteVex(intpos);//删除顶点pos的信息
voidInsertVex(intnum,Tname);//在num的位置上插入一顶点,值为name
voidDeleteArc(inti,intj);//在图中删除一条边,其依附的两个顶点的编号为i和j
voidInsertArc(inti,intj,intn);//在图中插入一条边,其依附的两个顶点的编号为i和j
private:
Tvertex[MaxSize];//存放图中顶点的数组
intarc[MaxSize][MaxSize];//存放图中边的数组
intvertexNum;//图的顶点数和边数
};
#endif
在图的类中,提供了如下成员函数:
(1)函数声明:
Graph
完成的功能:
构造函数,初始化具有n个顶点的图
(2)函数声明:
voidDijkstra
完成的功能:
求最短距离
(3)函数声明:
PutOutVexInfo
完成的功能:
取顶点信息
(4)函数声明:
PutOutArcInfo
完成的功能:
取边信息
(5)函数声明:
SetArc
完成的功能:
修改路径
(6)函数声明:
DeleteVex
完成的功能:
删除某顶点的信息
(7)函数声明:
InsertVex
完成的功能:
插入某个顶点
(8)函数声明:
DeleteArc
完成的功能:
删除某边的信息
(9)函数声明:
InsertArc
完成的功能:
插入某边及相应顶点
2.3功能函数实现
1.构造函数定义
前置条件:
图不存在
输入:
无
功能:
图的初始化
输出:
无
后置条件:
构造一个有值的图
Graph:
:
Graph(int*a,T*v,intn)//构造图
{
inti,j;
vertexNum=n;//顶点数
for(i=0;ifor(j=0;jarc[i][j]=10000;
for(i=0;ivertex[i]=v[i];//存储顶点信息
for(i=0;ifor(j=0;jarc[i][j]=*(a+i*n+j);
inttt=0;
}
2.取顶点信息函数定义
前置条件:
图已存在
输入:
无
功能:
输出图中所有顶点的数据信息
输出:
图中所有顶点的数据信息
后置条件:
图保持不变
voidGraph:
:
PutOutVexInfo()//取顶点
{
inti=0;//假设源点是第0个顶点,即顶点序号是0
if(i>vertexNum)throw"位置";//错误抛出异常
else{for(i=0;icout<}
}
}
3.修改路径函数定义
前置条件:
图已存在
输入:
顶点v1,v2
功能:
修改顶点v1、v2的路径
输出:
修改后图中所有的路径
后置条件:
图保持不变
voidGraph:
:
SetArc(intv1,intv2,intarclength)//修改路径
{//假设源点是第0个顶点,即顶点序号是0
if(v1>vertexNum||v2>vertexNum)throw"位置";//错误抛出异常
else
{arc[v1][v2]=arclength;//修改v1顶点到v2顶点的距离
arc[v2][v1]=arclength;
}
}
4.取边函数定义
前置条件:
图已存在
输入:
无
功能:
输出图中所有的路径
输出:
图中所有顶点的数据信息
后置条件:
图保持不变
voidGraph:
:
PutOutArcInfo()//输出图中所有的路径
{
inti=0;//假设源点是第0个顶点,即顶点序号是0
intj=0;
if(i>vertexNum||j>vertexNum)throw"位置";//错误抛出异常
else
{for(i=0;ifor(j=0;j
if(arc[i][j]<10000)//两点之间存在路径
cout<<"从"<"<}
}
}
}
5.插入顶点函数定义
前置条件:
图已存在
输入:
顶点name,位置i
功能:
在图中i位置插入一个顶点name
输出:
如果插入不成功,抛出异常
后置条件:
如果插入成功,图中增加了一个顶点
voidGraph:
:
InsertVex(intnum,Tname)//在图中插入一个顶点,其编号为i,值为value
{//假设源点是第0个顶点,即顶点序号是0
if(num<0||num>vertexNum)throw"位置";//如果num输入不正确抛出异常
introw;//行
intcol;//列
intnumv;//最后一个顶点所在的位置
numv=vertexNum-1;
if(num>-1)//num存在
vertexNum++;//顶点数加1
for(inti=numv;i>num-1;i--)//i从最后一个顶点的下一个位置开始循环
vertex[i]=vertex[i-1];//把从num位置的顶点到最后一个顶点均向后移一位
vertex[num]=name;//把要插入的顶点的值放在num位置上
for(row=numv;row>=0;row--)//把从num列到最后一列的元素均向下移一列
{
for(col=numv;col>=num;col--)
arc[row][col+1]=arc[row][col];
arc[row][num]=10000;
}
for(row=numv;row>=num;row--)//把从num行到最后一行的元素均向下移一行
for(col=0;col<=numv+1;col++)
arc[row+1][col]=arc[row][col];
for(col=0;colarc[num][col]=10000;//把num位置所在的行、列的值均置为无穷大
}
6.删除顶点函数的定义
前置条件:
图已存在
输入:
顶点pos
功能:
在图中删除顶点pos
输出:
如果删除不成功,抛出异常
后置条件:
如果删除成功,图中减少了一个顶点,相应顶点所建立的边也消去
voidGraph:
:
DeleteVex(intpos)//删除第pos个顶点
{//假设源点是第0个顶点,即顶点序号是0
if(pos<0||pos>MaxSize)throw"位置";//如果pos输入不正确抛出异常
introw;//行
intcol;//列
intnumv=vertexNum;//numv等于顶点数
if(pos>-1)//pos存在
{
for(inti=pos;ivertex[i]=vertex[i+1];//把从pos到最后的每个点的位置依次向前移一位
vertexNum--;//顶点数减1
for(row=0;row{
for(col=pos;colarc[row][col]=arc[row][col+1];//把从pos列到最后一列的元素均向前移一列
arc[row][numv-1]=10000;//把pos所在的列上的值置为无穷大
}
for(row=pos;rowfor(col=0;colarc[row][col]=arc[row+1][col];//把从pos行到最后一行的元素均向上移一行
}
}
7.求最短距离函数定义
前置条件:
图已存在
输入:
顶点v,endv
功能:
假如endv存在,求v到endv的最短路径;假如不输入endv,则求v到任意顶点的最短路径
输出:
所求得的最短路径及所经历的位置
后置条件:
图保持不变
voidGraph:
:
Dijkstra(intv,intendv)//求最短路径,从v顶点到endv点的最短路径
{if(v>vertexNum)throw"位置";//v顶点或endv顶点输出不正确则抛出异常
intnumv=vertexNum;//顶点数
intdist[MaxSize];//最短长度
intpath[MaxSize];//当前找到的最短路径
ints[MaxSize];//存放源点和已生成的终点的集合
intmax=10000;//代表无穷大
inti,j,k,wm;
for(i=0;i{
dist[i]=arc[v][i];
if(i!
=v&&dist[i]path[i]=v;//当前找到的最短路径为v
else
path[i]=-1;//否则v与i顶点不存在路径
s[i]=0;//给s集合确定初值0
}
s[v]=1;dist[v]=0;//将顶点v本身排除在外
for(k=0;k{
wm=max;j=v;//确定当前最短路径wm及顶点的序号j
for(i=0;i{
if(!
s[i]&&dist[i]{
j=i;
wm=dist[i];//把当前找到的路径确定为最大值
}
}
s[j]=1;
for(i=0;i{
if(!
s[i]&&dist[j]+arc[j][i]{
dist[i]=dist[j]+arc[j][i];path[i]=j;//dist[i]取最小值
}
}
}
if(endv=0)//endv点存在
{
stringmmm="";//初始化字符串
intj=endv;
while(j>-1)
{
stringnnn=vertex[j];//依次把顶点存放在nnn字符串中
nnn+=mmm;
mmm=""+nnn;
j=path[j];
}
cout<<"从"<"<"<}
else//endv点不存在
for(i=0;i{
stringmmm="";//初始化字符串
intj=i;
while(j>-1)
{
stringnnn=vertex[j];//依次把顶点存放在nnn字符串中
nnn+=mmm;
mmm=""+nnn;
j=path[j];
}
cout<<"从"<"<"<}
}
8.删除边信息函数定义
前置条件:
图已存在
输入:
顶点n、w
功能:
在图中删除顶点n、w依附的边
输出:
如果删除不成功,抛出异常
后置条件:
如果删除成功,图中减少了一条边
voidGraph:
:
DeleteArc(intn,intw)//删除i、j两顶点依附的边
{
if(n>MaxSize||w>MaxSize)throw"位置";//如果输入不正确抛出异常
arc[n][w]=arc[w][n]=10000;//删除w顶点和n顶点之间的路径
}
9.插入边及相应顶点函数定义
前置条件:
图已存在
输入:
顶点i、j
功能:
在图中插入顶点i、j及其所依附的边
输出:
如果插入不成功,抛出异常
后置条件:
如果插入成功,图中增加了一条边
voidGraph:
:
InsertArc(inti,intj,intn)//在图中插入一条边,其依附的两个顶点的编号为i和j
{
if(i>MaxSize||j>MaxSize)throw"位置";//如果输入不正确抛出异常
arc[i][j]=n;
arc[j][i]=n;
cout<<"从"<"<}
2.4算法分析
1.输出边信息功能算法分析
根据Dijkstra算法求单源点最短路径问题,设n是图中顶点的个数,第一个循环执行n-1次;第二个循环也执行n-1次,内嵌两个并列的循环,第一个循环是在数组dist中求最小值,执行n-1次,第二个循环是修改数组dist和path,需要执行n次,所以总的时间复杂度是O(n2)。
然后每次以一个顶点为源点,调用Dijkstra算法n次。
这样,便可求得每一对顶点之间的最短路径,再显示出来即为各边的信息。
显然,时间复杂度为O(n3)。
2.求最短路径功能算法分析
求最短路径即为单源点最短路径问题,由上得时间复杂度为O(n2)。
2.5程序调试
在voidPutOutVexInfo()函数中,当要输出所有顶点数据信息时,源点位置有可能超出范围,超出范围则程序运行异常,因此要判断源点位置是否超出,解决方法用判断语句列出超出条件,if(i>vertexNum)throw"位置";此句可防止位置超出范围。
此类问题还发生在该程序的类封装的各程序中,都采用相同的办法解决范围超出问题。
在求最短路径函数voidDijkstra(intv,intendv)中,求v顶点到endv点的最短路径时,两点间可能不存在路径,此时程序运行结果会异常。
解决办法是先判断两点间是否有路径,再输出最短路径,用语句if(i!
=v&&dist[i]3测试运行
3.1开始界面测试
开始界面如图3.1所示。
图3.1开始界面
3.2输出顶点信息功能测试
根据菜单提示输入0执行顶点信息输出功能,则显示各顶点信息如图3.2所示。
图3.2顶点输出功能测试结果
则程序能正确输出各顶点信息。
3.3输出边信息功能测试
根据菜单提示输入1执行边信息输出功能,则显示各顶点信息如图3.3所示。
图3.3边信息输出功能测试结果
则程序能正确输出各边信息。
3.4修改功能测试
根据菜单提示输入2执行修改功能,即可对两顶点间的距离进行修改,然后输入要修改的两顶点,再输入修改的距离值,执行结果如图3.4所示。
图3.4修改功能测试结果
此时则成功修改了两顶点间的距离。
3.5求最短路径功能测试
根据菜单提示输入3执行求最短路径功能,首先提示输入源顶点,输入始点后再提示“请输入结束顶点,若要全部显示请输入88:
”,分别输入结束点和88后,则输出相应的最短路径信息,运行结果如图3.5和图3.6所示。
图3.5输入结束点求最短路径运行结果
图3.6输入88求最短路径运行结果
分别正确显示了有结束点和无结束点时最短路径。
3.6删除顶点功能测试
根据菜单提示输入4执行删除顶点功能,提示输入要删除的顶点,运行如图3.7所示。
图3.7删除顶点功能运行结果
运行删除该顶点成功。
3.7插入顶点功能测试
根据菜单提示输入5执行插入顶点功能,提示输入要插入的顶点的位置和名称,运行如图3.8所示。
图3.8插入顶点功能测试
再根据菜单中提示输入0执行输出顶点信息功能,输出结果如图3.9所示。
图3.9插