单元点最短路径算法的实现 课程设计Word文档下载推荐.docx
《单元点最短路径算法的实现 课程设计Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《单元点最短路径算法的实现 课程设计Word文档下载推荐.docx(17页珍藏版)》请在冰豆网上搜索。
确定问题的输入数据集合。
2)逻辑设计:
对问题描述中涉及的操作对象定义相应的数据类型,并按照以数据结构为中心的原则划分模块,定义主程序模块和各抽象数据类型。
逻辑设计的结果应写出每个抽象数据类型的定义(包括数据结构的描述和每个基本操作的功能说明),各个主要模块的算法,并画出模块之间的调用关系图;
3)详细设计:
定义相应的存储结构并写出各函数的伪码算法。
在这个过程中,要综合考虑系统功能,使得系统结构清晰、合理、简单和易于调试,抽象数据类型的实现尽可能做到数据封装,基本操作的规格说明尽可能明确具体。
详细设计的结果是对数据结构和基本操作做出进一步的求精,写出数据存储结构的类型定义,写出函数形式的算法框架;
4)程序编码:
把详细设计的结果进一步求精为程序设计语言程序。
同时加入一些注解和断言,使程序中逻辑概念清楚;
5)程序调试与测试:
能够熟练掌握调试工具的各种功能,设计测试数据确保程序正确。
调试正确后,认真整理源程序及其注释,形成格式和风格良好的源程序清单和结果;
6)结果分析:
程序运行结果包括合法的输入及其输出结果和含有非法的输入及其输出结果。
算法的时间、空间复杂性分析;
7)编写课程设计报告;
以上要求中前三个阶段的任务完成后,先将设计说明书的草稿交指导老师面审,审查合格后方可进入后续阶段的工作。
设计工作结束后,经指导老师验收合格后将设计说明书打印装订。
指导教师(签字):
教研室主任(签字):
批准日期:
2014年2月23日
课程设计评阅
评语:
指导教师签名:
年月日
指导教师:
余冬梅教研室负责人:
申静
摘要
本系统以VC++作为软件开发环境,C语言作为程序开发语言,邻接矩阵作为存储结构,设计与实现了最短路径运算。
该系统实现了有向图的存储、最短路径的运算等主要功能。
依照该系统可以解决生活中许多问题,比如交通路线的选择,工程时间的预算等等,让人们可以做出合理的选择。
本系统通过分析课题的背景、意义、要求,分别从课题描述、逻辑设计、算法设计、调试与测试等各个方面详细介绍了系统的设计与实现过程,最后对系统的完成情况进行了总结。
界面清晰,操作简单,易于用户接受。
关键词:
VC++;
邻接矩阵;
最短路径
目录
1课题描述1
2问题分析与任务定义2
2.1问题分析2
2.2任务定义2
3算法设计3
3.1图的邻接矩阵的存储结构3
3.2Dijkstra算法思想4
4系统逻辑设计5
4.1主函数流程图如图4.1所示5
4.2Create函数流程图如图4.2所示6
4.3Dijkstra函数流程图如图4.3所示8
4源代码11
5调试与测试14
6总结16
参考文献17
1课题描述
乘车旅行的人大多数都希望找出到目的地尽可能短,花费少的行程,那么如何找出从出发点到目的地的最短路径?
由于路径比较多,所以用手工计算起来比较复杂,抽象,因此人们用计算机语言代替手工计算来求得最短路径。
而在计算机语言中迪杰斯拉算法比较常用,简捷,故人们经常借助计算机程序用迪杰斯拉算法求得单源点的最短路径,这样可以广泛的提高效率,而且条理清晰,通俗易懂。
2问题分析与任务定义
2.1问题分析
本系统是要解决的是单源点最短路径问题,设计程序,实现最短路径的求法,系统需要达到的主要功能如下:
(1)编写算法能够建立带权图,并能够用Dijkstra算法求该图的最短路径。
(2)能够选择图上的任意一顶点做为开始节点。
最短路径输出不必采用图形方式,可顶点序列方式输出。
(3)根据课设题目要求,拟将整体程序分为三大模块。
两个子模块相互独立,没有嵌套调用的情况,在主模块中调用上面两个子模块。
2.2任务定义
根据课设题目要求,拟将整体程序分为三大模块。
两个子模块相互独立,没有嵌套调用的情况,在主模块中调用上面两个子模块以下是三个模块的大体分析:
(1)建立有向图的存储结构。
(2)应用Dijkstra算法求出该有向图的最短路径。
(3)在主函数中调用两个子函数,完成最短路径的程序设。
3算法设计
3.1图的邻接矩阵的存储结构
一个图的邻接矩阵表示唯一的。
故在图的邻接矩阵表示中,除了需要用一个二维数组存储顶点之间相邻关系的邻接矩阵外,通常还需要使用一个具有n个元素的一维数组存储顶点信息,其中下标为i的元素存储顶点vi的信息。
本设计是基于类C语言的算法描述,因此,图的邻接矩阵的存储结构定义如下:
#defineMVNum50
typedefstruct{
VertexTypevexs[MVNum];
Adjmatrixarcs[MVNum][MVNum];
}Mgraph;
在本系统中,以邻接矩阵存储有向图,如图3.1a中有向图G所示,其邻接矩阵为图3.1b所示:
图3.1bG的邻接矩阵
∞∞10∞30100
∞∞5∞∞∞
∞∞∞50∞∞
∞∞∞∞∞10
∞∞∞20∞60
∞∞∞∞∞∞
b
a
e
f
5
50
图3.1a有向图G
c
d
100
60
30
20
10
3.2Dijkstra算法思想
(1)Dijkstra算法核心是贪心,实质是按路径长度递增产生诸顶点的最短路径算法。
用自然语言描述如下:
初始化S和D,置空最短路径终点集,置初始的最短路径值;
S[v1]=TRUE;
D[v1]=0;
While(S集中的顶点数<
n)
{
开始循环,每次求的v1到某个v顶点的最短路径,并将v加到S集中;
S[v]=TRUE;
更新当前最短路径及距离。
}
(2)Dijkstra算法结束后,通过设置一个数组记录下一个节点的前趋节点,然后通过倒叙的方式输出该最短路径。
4系统逻辑设计
4.1主函数流程图如图4.1所示
开始
输入顶点个数和边数m,n
输入数据
调用Create函数
建立图的邻接矩阵
N
调用Dijkstra函数
Y
3.1主函数流程图
请输入初始点v
4.2Create函数流程图
求得最短路径
k=1
结束
图4.1主函数流程图
4.2Create函数流程图如图4.2所示
定义顶点序号i=1,顶点数m,边数n
i<
=m
存入一维向量G.vexs[i]=i
i=i+1
i=1
j=1
j<
∞10∞30100
对邻接矩阵m*m个单元初始化
G.arcs[i][j]=Maxint
j=j+1
接下一页
接上一页
变量k=1
k<
=n
定位i,j
i=a-‘a’+1,j=b-‘a’+1
G->
arcs[i][j]=w
给邻接矩阵有关单元赋权值w
G.arcs[i][j]=w
k=k+1
图4.2Create函数流程图
4.3Dijkstra函数流程图如图4.3所示
定义G中v1到其余顶点v的最短路径、带权长度及最短路径终点的集合intD[MVNum],P[MVNum]
booleanS[MVNum]定义顶点数intm
v=1
v<
置空SS[v]=FALSED[v]=G.arcs[v1][v]
若权值小于最大值无穷D[v]<
Maxint
P[v]=0
P[v]=v1
v=v+1
初始化,v1顶点属于s集D[v1]=0;
S[v1]=TRUE
开始主循环,每次求得v1到某个v顶点的最短路径,并加v到s集
i=2
=mmmm
当前所知离v1顶点的最近距离min=Maxint
顶点变量w=1
w<
、
!
S[w]&
&
D[w]<
min
v=wW顶点离v1更近min=D[w]
S[v]=TRUE
w=w+1
w=1
D[v]+G.arcs[v][w]<
D[w]
修改D[w],P[w]D[w]=D[v]+G.arcs[v][w]
P[w]=v
输出数据p[v]
图4.3Dijkstra函数流程图
4源代码
#include<
stdio.h>
stdlib.h>
#defineMaxint1111
typedefcharVertexType;
//定义顶点
typedefintAdjmatrix;
typedefenum{FALSE,TRUE}boolean;
typedefstruct{//图的邻接矩阵
//顶点向量存放顶点的一维数组
Adjmatrixarcs[MVNum][MVNum];
//邻接矩阵二维数组
}MGraph;
//定义邻接矩阵结构类型
voidCreateMGraph(MGraph*G,intm,intn)//采用数组(邻接矩阵)表示法,构造图G
inti,j,k,w;
chara,b;
for(i=1;
=m;
i++)//构造顶点向量
G->
vexs[i]=i;
i++)//初始化邻接矩阵
for(j=1;
j++)
arcs[i][j]=Maxint;
printf("
输入%d条边的i,j及w:
\n"
n);
for(k=1;
=n;
k++)//构造邻接矩阵
{
fflush(stdin);
scanf("
%c,%c,%d"
&
a,&
b,&
w);
//输入一条边依附的顶点及权值
i=a-'
a'
+1;
j=b-'
G->
arcs[i][j]=w;
//弧<
i,j>
的权值
}
有向图的存储结构建立完成!
);
**********************************\n"
voidDijkstra(MGraphG,intv1,intm)
//用Dijkstra算法求G中v1顶点到其余顶点v的最短路径p[v]及带权长度D[v]
intD[MVNum],P[MVNum];
intv,i,w,min;
booleanS[MVNum];
//S以求得最短路径的终点的集合
for(v=1;
v++)
{
S[v]=FALSE;
D[v]=G.arcs[v1][v];
if(D[v]<
Maxint)
P[v]=v1;
else
P[v]=0;
}
D[v1]=0;
//初始化,v1顶点属于s集
//开始主循环,每次求得v1到某个v顶点的最短路径,并加v到s集
for(i=2;
i++)//其余n-1个顶点
min=Maxint;
//当前所知离v1顶点的最近距离
for(w=1;
w++)
if(!
min)//w顶点在v-s中
{
v=w;
min=D[w];
//w顶点离v1顶点更近
}
S[v]=TRUE;
for(w=1;
w++)//更新当前最短路径及距离
if(!
(D[v]+G.arcs[v][w]<
D[w]))//修改D[w]和P[w],w属于v-s
{
D[w]=D[v]+G.arcs[v][w];
P[w]=v;
}
printf("
路径长度-----------路径\n"
i++)
%5d"
D[i]);
%12c"
i-1+'
v=P[i];
while(v!
=0)
printf("
<
-%c"
v-1+'
v=P[v];
}
voidmain()
{
MGraphG;
intm,n,v;
charch;
输入所需图的顶点个数和边数m,n:
"
scanf("
%d,%d"
m,&
n);
CreateMGraph(&
G,m,n);
while(v<
=m)
求最短路径,请输入初始点v:
fflush(stdin);
%c"
ch);
v=ch-'
Dijkstra(G,v,m);
}
5调试与测试
(1)合法数据测试结果如图5.1所示
图5.1合法数据测试结果
(2)非法数据测试结果如图5.2所示
图5.2非法数据测试结果
当前任务已达到任务目标,对于n个顶点的有向图,求一个顶点到其他顶点的最短路径的时间为O(n),调整最短路径的循环共执行n-1次,所以,时间复杂度是O(n2)。
采用邻接矩阵存储有向图,应处理每两个顶点之间的关系,所以空间复杂度为O(n2)。
6总结
本次课程设计涉及到的范围很广,让我比较系统的对C语言和数据结构知识进行了一次整理和复习。
本系统存在的问题主要是程序完成后,调试时没有发现问题,但是当输入开始节点后,运行框却不停的出现”<
-a”,后来重新检查程序时发现for循环的括号后面多了一个“;
”,去掉该分号之后,程序可以运行。
在这次课程设计中我体会到C语言超强的逻辑性以及能够熟练使用VC++编译环境的重要性,对C语言与数据结构这两门课程有了新的认识,它们既有联系,又相互区别,在编写程序过程中要灵活应用。
我对数据结构的理解还有待加强,这次课程设计应用的算法是Dijkstra算法。
在学习的过程中自己对这方面的知识比较生疏,所以在算法设计过程中比较困难,尤其是设计Dijkstra算法的流程图时,发现自己对流程图这一块知识存在漏洞,有待加强。
目前,该课设的缺点是:
①采用邻接矩阵存储图时,测试其边的数目,必须检查边二维数组的所有元素,时间复杂度为O(n2),这对于顶点很多而边较少的图(稀疏图)是非常不合算的;
②输出结果不是有序的;
这两点还有待改进。
在这次课程设计中,我深刻体会到了,不管做任何事情,只要持之以恒,一定会取得成功。
参考文献
[1]谭浩强.C程序设计(第三版)[M].北京:
清华大学出版社,2005
[2]严蔚敏,吴伟民.数据结构(C语言版)[M].北京:
清华大学出版社,2002
[3]李春葆.数据结构教程上机实验指导[M].北京: