最短路径拯救007 课程设计报告.docx
- 文档编号:7186948
- 上传时间:2023-01-21
- 格式:DOCX
- 页数:25
- 大小:32.43KB
最短路径拯救007 课程设计报告.docx
《最短路径拯救007 课程设计报告.docx》由会员分享,可在线阅读,更多相关《最短路径拯救007 课程设计报告.docx(25页珍藏版)》请在冰豆网上搜索。
最短路径拯救007课程设计报告
《数据结构课程设计》报告
题目:
最短路径—拯救007问题
专业
计算机科学与技术
学生姓名
丁亚敏
班级
B计算机115
学号
1110704503
指导教师
巩永旺
完成日期
2013年1月11日
一、简介
最短路径是,在一个图中,若从一个顶点到另一个顶点存在着一条路径(这里只讨论无回路的简单路径),则称该条路径长度为为该路径上所有经过的边的数目,它也等于该路径上的顶点数减1。
由于从一个顶点到另一个顶点可能存在着多条路径,在每条路径上所经过的边数可能不同,把路径长度最短(经过的边数最少)的那条路径叫做最短路径,其路径长度叫做最短距离。
这是对无权图而言的,若图是帯权图,则把从一个顶点vi到vj的一条路径上所有经过边的权值之和定义为该路径的带权路径长度。
把带权路径长度最短的那条路径称为该有权图的最短路径,其路径长度称为最短距离。
Dijksra算法:
如何求解从一个顶点到其余每个顶点的最短路径呢?
狄克斯特拉于1959年提出了解决此问题的一种按路径长度的递增次序产生最短路径的算法。
基本思想是,从图中给定源点到其他各个顶点之间客观上应个存在一条最短路径,在这组最短路径中,按其长度的递增次序求出到不同顶点的最短路径和路径长度。
图是一种较线性结构和树形结构更为复杂的非线性数据结构,这种复杂性主要来自数据元素之间的复杂关系。
在图结构中,任何两个数据元素之间都可能存在关系,一般用顶点表示数据元素,而用顶点之间的连线表示数据元素之间的关系。
图的二元组定义为:
G=(V,E)。
其中V是非空的顶点集合,E是V上的二元关系集合。
题目内容:
看过007系列的电影的人们一定很熟悉JamsBond这个世界上最著名的特工了。
在电影“LiveAndLetDie”中JamsBond被一组毒品贩子抓住并且关到湖中心的一个小岛上,而湖中有很多凶猛的鳄鱼。
这时JamsBond做出了一个最惊心动魄的事情来逃脱——他跳到了最近的鳄鱼的头上,在鳄鱼还没有反映过来的时候,他有跳到另一支鳄鱼的头上.。
。
。
。
。
。
最后他终于安全地跳到了湖岸上。
假设湖是100*100的正方形,设湖的中心在(0,0),湖的东北角的坐标是(50,50)。
湖中心的圆环小岛的圆心在(0,0),直径是15.。
一些凶残的鳄鱼分布在湖中不同的位置。
现已知的湖中的鳄鱼的位置和JamsBond可以跳的最大距离,请你告诉JamsBondyitiao最短的到达湖边的路径。
他逃出去的路径长度等于他跳的次数。
二、算法说明
程序从“input.txt”文件中读取输入信息,这个文件包含了多组输入数据。
每组输入数据的起始行中包含了两个整数n和d,n是鳄鱼的数量而且n<=100,d是007可以跳的最大距离而且d>0。
起始行下面的每一行是鳄鱼的坐标(x,y),其中x,y都是整数,而且没有任何两只鳄鱼出现在同一位置。
Input.txt文件以一个负数结尾。
输出要求:
程序结果输出到output.txt文件中。
对于每组输入数据,如果007可以逃脱,则输出到output.txt文件的内容格式如下:
第一行是007必须跳的最小步数,然后按照跳出顺序记录跳出路径上的鳄鱼坐标(x,y),每行一个坐标。
如果007不可能跳出去,则将-1写入文件。
如果这里有很多个最短路径,只需输入其中的任意一种。
输入例子:
410/*第一组输入数据*/
170
270
370
450
110/*第二组输入数据*/
2030
-1
输出例子:
5/*对应第一组数据的输出*/
170
270
450
-1/*对应第二组数据的输出*/
提示:
将每个鳄鱼看作图中的每一个顶点。
如果007可以从A点跳到B点,则A和B之间就有一条边。
主要数据结构与算法:
为了记录007跳过的路径,可定义为如下结构:
typedefunsignedintVertez;
typedefdoubleDistance;
typedefstructGraphNodeRecord{
intX;/*x轴坐标*/
intY;/*y轴坐标*/
unsignedintStep;/*记录到本节点一共跳了多少步*/
VertexPath;/*指向本节点的父节点,即跳到本节点之间007所在节点*/
}GraphNode;
typedefGraphNode*Grapha;
寻找跳出路径的算法:
/*读出一组测试数据返回007跳过的路径Graph,*Bank记录最短到达湖岸的路径。
该算法实际上是应用队列对图惊醒广度搜索,以寻找到岸边的最短路径,其中入队列与出队列函数分别是Inject()和Pop()*/
Graphread_case(FILE*InFile,intnum,Vertex*Bank,DequeD)
{
GraphG=NULL;
DistanceJamesJump;
VertexV;
intx,y;
inti,Times;
*Bank=0;/*初始化跳出的路径的记录*/
fscanf(Infile,”%lf”,&JamesJump);/*读取步长*/
if(Bondcanjumotothebankdirectly)
{
*Bank=1;/*直接跳出的情况*/
}
elseif(num>0)/*007必须经过鳄鱼头上的情况*/
{
num+=2;
G=GraphNew”(num);
for(i=2;i { if(BondcanjumptoG[i]fromisland)/*判断是否能从岛上跳上该点*/ { G[i].Path=1; G[i].Step=1;/*一步*/ if(BondcanjumptobankfromG[i])/*判断该点是否能跳出*/ { *Bank=i;/*007可以跳出,记录该点*/ Skipothercrocodile break; } else Inject(i,D);/*插入该点,并开始下一个检测*/ } } while(! IsEmpty(D))/*只经过一只鳄鱼无法跳出,必须还要跳到其他鳄鱼的情况*/ { V=Pop(D); for(i=2;i { if(bondcanjumpfromvtoi,andstepofi>stepofv+1) { G[i].Path=V; G[i].Step=G[V].Step+1;/*把i点练到v点后面*/ if(bondcanjumpfromitobankandthepathisshorterthanothers) *Bank=i; else Inject(i,D); } } } } returnG; } 在执行完算法read_case后,*Bank值可能如下3种可能: (1)0,意味着007无法逃脱出去; (2)1,意味着007可以直接从岛上跳出去,而不用经过鳄鱼的脑袋; (3)k,返回的第k点是007经过最短路径逃出鳄鱼潭是经过的最后一个顶点。 可以根据G[k]的path参数来追踪该点的上一点,由此类推可以得到007逃脱的最短路径。 三、测试结果 对于本程序,需要应用各种类型的测试用例来进行测试。 一般来说,可以设计一下几种类型的测试用例。 •007步长很大,以至于可以直接跳出,例如: 143 -1 •007不可能逃出去的情况(根本就没有鳄鱼),例如: 11 -1 •一般情况的例子,例如: 410 170 270 370 450 210 2030 -1 •最短路径有多条,只需要输出任意一种即可,例如: 2510 88 99 1010 1111 1212 1313 1414 1515 1616 1818 2020 2323 2525 2727 2828 2929 3131 3333 3535 3838 4141 4444 4646 4747 4949 输出结果: 7 99 1616 2323 2828 3535 4141 •input.txt文件中,名称不正确、空文件、缺少部分输入等不规范情况,例如: 510 1010 -2530 3030 注: 缺少鳄鱼点(应有5个鳄鱼点)和文件结尾符(-1)。 运行结果: 输入数据: 043 01 410 170 270 370 450 110 2030 2510 88 99 1010 1111 1212 1313 1414 1515 1616 1818 2020 2323 2525 2727 2828 2929 3131 3333 3535 3838 4141 4444 4646 4747 4949 1020 1010 2020 1030 输出结果 1 -1 5 170 270 370 450 -1 7 99 1616 2323 2828 3535 4141 3 1010 1030 3 -10-10 -10-30 3 -10-10 -30-10 3 1010 3010 3 1010 1030 -1 7 1010 1015 2015 2222 3120 4020 -1 7 -10-8 -15-15 四、分析与探讨 1.明确题目中的已知条件 (1)007被关的小岛在湖的中心; (2)小岛是圆形,圆心在(0,0),而且直径是15; (3)没有两只鳄鱼在同一个位置; (4)鳄鱼的坐标值都是整数。 2.一些判断007是否能跳出的细节 (1)判断007是否能够直接从岛上跳到湖岸: 由已知条件可得,湖是一个正方形,边长为100,中心是在(0,0),四个顶点分别是(50,50),(50,-50),(-50,-50),(-50,50)。 而湖中小岛的直径是15.所以如果007可以跳大于等于(50-15/2)=42.5,他就可以直接从小岛跳到湖岸,而不用经过鳄鱼。 (2)判断007是否能够直接从岛上跳到湖中点A: 已知半径是7.5,假设点A的坐标是(x,y),007的步长是L,则当点A到中心(0,0)的距离小于等于007的步长加上小岛的半径7.5的时候就能确定007可以从岛上跳到点A,即: x*x+y*y<=(L+7.5)*(L+7.5)。 (3)判断007是否能够从点A跳到点B: 假设007的步长是L所以如果两点之间的距离小于等于L,则判断007可以从A跳到B,即(A.x-B.x)^2+(A.y-B.y)^2<=L*L;其他情况时007不能从A点跳到B点。 (4)判断007是否能够从点A跳到湖岸: 当从A点到湖岸的距离小于等于007的步长的时候,说明他可以从A点跳到湖岸,|A.x|+L>=50或|A.y|+L>=50;其他情况时007不能从A点跳到湖岸。 五、小结 经历了这次课程设计实践,我感触颇深。 此前一直错误的以为做课程设计其实是件很简单的事情,根本不需要兴师动众而且花费那么长的时间,两三天足矣。 在此错误认识的引导下,也就没怎么把它当回事,只打算随随便便应付一下,完工交差。 但是等到真正亲历后才发现原来自己是多么的愚蠢可笑,自己的想法又是多么的幼稚、荒谬。 做的过程并不顺利,而其中的种种遭遇更是让我反省良久。 一路坚持下来,其中的艰辛也许只有经历过才能真正体会。 不过,经过一番实践后,当看到自己亲手做的东西就那么真实的摆在眼前,曾经的心血与付出终于有了回报,那份激动与喜悦的心情又岂是三言两语说得清楚的! “如人饮水,冷暖自知”,现在我是真的体会到了。 总的来说,我觉得这次设计实践收获颇丰,于今后的学业、步入社会后参加工作乃至做人做事都是一笔不小的财富! 通过这次课程设计,我懂得了实践的重要性、团队合作精神的可贵以及做事前的充足准备与做事过程中的坚持和细心谨慎对于高质高效地完成一项工作的特殊意义。 任何事情都有一个循序渐进的过程,知难而进、勇往直前,只有这样才有可能领略险峰的无限风光。 治学、做人又何尝不是如此呢? 先说实践。 关于实践,前人曾留有十二字箴言: “实践是检验真理的唯一标准”,经过这次课程设计,我所理解的实践已远不只此。 人说“爱过才知情深,醉过方知酒浓”,我以为,只有实践才会出真知,没有实践,任何理论、见解都是苍白无力的。 眼之所见、心之所想大多数时候并不就是手之所为。 在动手尝试之前,我可以算是一个眼高手低的人。 课程设计的题目下来了,共有三个可供选择。 相较之下我选了做“拯救007”,本以为这是最简单的,基本上可以不费多大心力即轻松搞定。 因此开始的几天里也没怎么刻意着手这件事情。 事实却是,等到我真正做了才发现随着问题的不断出现和为此而查阅许多相关的资料,花了那么多的时间与精力,做的过程还是如此的困难重重,并且做出来的东西也并非尽善尽美。 方知许多事情并非都如人所想,不实践、不参与是无论如何也不会明白的。 实践之重要正在于此! 这段小小的经历使我感触很深,也教会我在以后的学习与工作中不要再眼高手低,任何事情都需亲自尝试后再做定断。 牢记“眼之所见、心之所想非手之所为也! ” 接下来再说着手前的准备。 三国时诸葛亮草船借箭有赖“万事俱备,只欠东风”,而我的设计能顺利进行也必须有充足的准备作为后盾。 只可惜在一开始的时候由于并不很重视因此也未意识到这一点,导致做的过程中停停找找、找找停停,严重影响了设计进度和效率,并且这种临阵磨枪式的做法也使得准备很不充分,往往是急需要用的东西找也找不到,如某控件类的方法如何使用、其原型或者参数的类型与意义为何等等。 这样一来,自然会遇到重重困难。 我想,如果在动手之前已经做好了充足准备,必然会少遇到很多麻烦,也不会一度出现举步维艰的情况。 当然了,这次还只是一个小小的设计,如果换成是某个大型系统的设计岂不是无法想象? 所以这次经历也算是给了我一个教训: 千万不要打无准备的仗! 早准备方保无虞。 说到了准备,也得说说做事过程中的坚持与细心谨慎。 很难想象如果没有坚持到底的勇气和不懈的努力,当一个人面对困难时能迎难而上并一路坚持走下来。 当初我选定这个设计课题时正是考虑到它简单、易完成(当然事实并非如此),不过后来做的时候不断出现新的问题,而且有些还是从理论上无法解释的,这时我就在想算了吧,这么难搞,还是换别的做。 正好其他同学做的在网上找到了很多原本的版本,因而做起来就不费吹灰之力。 当时几乎就在一念之间转了方向,好在随后终于做成功了一部分功能。 这点小小的成功让我体会到了自己动手的乐趣与成功后的喜悦,在此激励之下,幸而坚持了下来。 回味其中的艰辛,尽享成功的喜悦,纵是雏鹰试翼之作,毕竟自己所为,比之其他同学照搬别人的代码以完成任务却不知到底做了什么、又有什么收获,不是更有意义吗? 能够坚持即已成功一半。 世上无难事,唯恐少坚持! 此外,在做的过程中不可能是一帆风顺的,必然免不了频繁出错。 这一方面是由于输入时的粗心大意造成的,另一方面则是编写的代码本身的问题。 对于前者,如果能在操作时做到细心谨慎,当然可以避免。 即便免不了输入错误,在调试的过程中也应细心谨慎,惟其如此,方可免去许多麻烦,保证软件设计的质量与效率。 由于要不断的调试,而VC6.0对于用户所作的改动会自动保存,因此就可能出现保存了修改后错误的结果,反而将前面做好的调试无误的内容覆盖掉的情况。 如果没有时时保持细心谨慎的态度,及时对调试无误的结果加以保存,将可能遭遇前 功尽弃的“灭顶之灾”。 不管怎样,时时处处细心谨慎,方保顺利无虞。 我想,无论是治学还是工作或是为人,这 样的一种态度都是至关重要的。 由于是初次设计,仅凭自己一人之力是很难完成的,所以大家或借助于网络,或借助于参考书籍、期刊资料等。 我也不例外,和几位同学一起研究设计方案及具体实现方法,并跑了好几趟图书馆,查资料,抄笔记,上网搜索资料,终于在大家的通力合作之下完成了这个项目。 一起做的过程大家朝着一个共同的目标努力,分工协作,互相交流,提出不同的想法,不断完善,不断进步,一个一个的问题迎刃而解,一个一个的功能不断做出来。 最后,集体的劳动终于换来了丰硕的成果(尽管并不完美)。 这次经历使我懂得了团队合作精神的可贵。 不仅如此,我觉得这次合作的过程真的是很愉快,很让人回味和怀念! 我想将来参加工作后这种合作还会有,参与合作,倡导这种合作精神是很可贵和重要的。 社会的进步使得人们面临的问题越来越复杂,迫使人们寻求集体的智慧、团队的力量来解决它们。 个人的力量终究是有限的,也不可能独立完成所有的事情,每个人都有义务和必要学会与别人沟通、交流,学会合作,参与合作,在合作的过程中培养这样一种意识。 对于将来的工作,这也是有重要意义的。 最后,值得一提的是编辑这份电子文稿,也使我学会了使用更多的Word功能。 虽然不是本次设计的正题,但毕竟也算是一种收获吧。 能够多学一点知识,总算也是一种成就。 课程设计即将结束,一个个挑灯夜战、激烈讨论的夜晚也已过去。 回顾整个过程,更清楚的认识到知识的欠缺,而自己所学的VC++知识只能算是皮毛,还有更多的东西需要我去研究,去掌握。 尽管如此,我也不会退缩、停滞不前,因为通过这次设计实践,我已初识VC++的庐山真面目。 这才是最重要的。 相信经过此次课程设计,日后将会有所改进。 此外,我还要感谢所有帮助过我的老师、同学,感谢你们在这几天里给我的帮助与鼓励。 正是因为你们的帮助与鼓励,我才能很好的完成这一次的课程设计,才能学到这么多的知识;也正是因为你们的帮助与鼓励,我真正认识到了团队力量的伟大,“团结就是力量。 ”感谢你们,谢谢。 参考文献 [1]刘振安,刘燕君.C程序设计课程设计[M].[北京]机械工业出版社,2004年9月 [2]谭浩强.C程序设计(第三版).清华大学出版社,2005年7月 [3]严蔚敏,吴伟民.数据结构(C语言版).清华大学出版社,1997年4月 [4]李志球《实用C语言程序设计教程》北京: 电子工业出版社,1999 [5]王立柱: C/C++与数据结构北京: 清华大学出版社,2002 [6]吴文虎《程序设计基础》北京: 清华大学出版社,2003 [7]郭福顺,王晓芬,李莲治《数据结构》(修订本),大连理工大学出版社,1997 [8]潘道才,陈一华《数据结构》,电子科技大学出版社,1994 附录: 源代码 本程序包含3个头文件和4个C源程序文件,分别是: Graph.hGraph.cDeque.hDeque.c error.herror.cmain.c 1.Graph.h #ifndef_GRAPH_H_ #define_GRAPH_H_ #defineISLAND_DIAMETER15/*小岛的直径*/ #defineLAKE_BOUNDARY_X50/*小岛到湖边的距离,在x轴上*/ #defineLAKE_BOUNDARY_Y50/*小岛到湖边的距离,在y轴上*/ #defineINFINITY10000/*可以跳的步数的最大值*/ typedefunsignedintVertex; typedefdoubleDistance; typedefstructGraphNodeRecord{ intX;/*x轴坐标*/ intY;/*y轴坐标*/ unsignedintStep;/*跳至该点的步数*/ VertexPath;/*记录上一个点*/ }GraphNode; typedefGraphNode*Graph; GraphGraphNew(intNodeNum); voidGraphDelete(GraphG); /*判断007是否能从起始处跳至该点(x,y)*/ intCheckForStart(intx,inty,Distanced); /*判断007是否能从该点跳至河岸*/ intCheckForEnd(intx,inty,Distanced); /*判断007是否能从点i跳至点j*/ intCheckForConnect(Graphg,Vertexi,Vertexj,Distanced); #endif 2.Graph.c #include"Graph.h" #include"error.h" #include /******创建新的Graph******/ GraphGraphNew(intNodeNum) { GraphG; inti; if(NodeNum<=0)returnNULL; G=malloc(NodeNum*sizeof(GraphNode));/*分配空间*/ CHECK(G); for(i=0;i { G[i].X=0; G[i].Y=0; G[i].Step=INFINITY; G[i].Path=0; } returnG; } /******删除一个Graph)******/ voidGraphDelete(GraphG) { if(G)free(G); } /*******判断007是否能从起始处跳至该点(x,y),步长是d******/ intCheckForStart(intx,inty,Distanced) { doublet; t=(ISLAND_DIAMETER+(d*2.0)); return(x*x+y*y)<=t*t/4.0; /*x^2+y^2<=(ISLAND_DIAMETER/2.0+d)^2*/ } /*******判断007是否能从该点跳至河岸,步长是d******/ intCheckForEnd(intx,inty,Distanced) { if(x<0)x=-x;/*取x的绝对值*/ if(y<0)y=-y;/*取y的绝对值*/ return(d>=LAKE_BOUNDARY_X-x)/*由于湖是个正方形,只需检查这两个距离*/ ||(d>=LAKE_BOUNDARY_Y-y); } /*******判断007是否能从点i跳至点j,步长是d******/ intCheckForConnect(Graphg,Vertexi,Vertexj,Distanced) { intx,y; x=g[i].X-g[j].X; y=g[i].
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 最短路径拯救007 课程设计报告 路径 拯救 007 课程设计 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)