课设-交通.docx
©/N”少火学程序设计课程设计报告学院:软件学院专业:软件工程班级学号:姓名:指导教师:王会青时间:2014年6月3.交通咨询系统设计最短路径问题专业:软件工程班级:1215班姓名:张鹏远学号:2012005391完成日期:2014/6/253.1 【问题描述】在交通网络非常兴旺,交通工具和交通方式不断更新的今天,人们在出差、旅游或做其他出行时,不仅关心节省交通费用,而且对里程和所需要的时间等问题也感兴趣。对于这样一个人们关心的问题,可用一个图结构来表示交通网络系统,利用计算机建立一个交通咨询系统。图中的顶点表示城市,边表示城市之间的交通关系。这个交通系统可以答复出行旅客提出的各种路径选择问题。例如,问题之一:“一位旅客要从A城到B城,他希望选择一条途中中转次数最少的路线。”假设图中每一站都需要换车,那么这个问题反映到图上就是要找一条从顶点A到顶点B的所含边数目最少的路径。我们只需要从顶点A出发对图作广度优先搜索,一旦遇到顶点B就终止。由此所得广度优先生成树上,从根顶点A到顶点B的路径就是中转次数最少的路径。路径上A与B之间的顶点就是路径的中转站,但这只是一类最简单的图的最短路径问题。系统还可以答复诸如此类的等等的路径选择问题。设计一个交通咨询系统,为出差、旅游或做其他出行的客人提供各种路径选择信息查询效劳。3.21 设计需求及分析】设计一个交通咨询系统,能让旅客咨询从任一个城市顶点到另一城市顶点之间的最短路径(里程)或最低花费或最少时间等问题。对于不同的咨询要求,可输入城市间的路程或所需时间或所需费用。本设计共分三局部,一是建立交通网络图的存储结构;二是解决单源最短路径问题;三是实现任两个城市顶点之间的最短路径问题。3.2.1建立图的存储结构邻接矩阵是表示图形中顶点之间相邻关系的矩阵。图的邻接矩阵是定义如下的n阶方设G=(V,E)是一个图,结点集为V=Wi2,,匕,G的邻接矩阵A=(%)“*“,%=(wij)nxn,当(vi,vj)或<vi,vj>EO或co,当(vi,vj)或<vi,vj>iE当邻接矩阵的行表头、列表头顺序一定时,一个图的邻接矩阵表示是唯一的。图的邻接矩阵表示,除了需用一个二维数组存储顶点之间的相邻关系的邻接矩阵外,通常还需要使用一个具有n个元素的一维数组来存储顶点信息,其中下标为i的元素存储顶点i的信息。因此,图的邻接矩阵的存储结构定义如下:#definfMVNum50最大顶点数typedefstructVertexTypevexsMVNum;顶点数组,类型假定为Char型AdjmatrixarcsMVNumMVNum;邻接矩阵,假定为int型MGraph;3.2.2单源最短路径最短路径的提法很多。在这里先讨论单源最短路径问题:即有向图(带权),我们希望找出从某个源点SV到G中其余各顶点的最短路径。为了表达方便,我们把路径上的开始点称为源点,路径的最后一个顶点为终点。那么,如何求得给定有向图的单源最短路径呢?迪杰斯特拉(Dijkstra)提出按路径长度递增产生诸点的最短路径算法,称之为迪杰斯特拉算法。迪杰斯特拉算法求最短路径的实现思想是:设G=(V,E)是一个有向图,结点集为,V=v,V2,v,J,cost是表示G的邻接矩阵,costij表示有向边i,j的权。假设不存在有向边i,j,那么CoStij的权为无穷大(这里取值为32767)。设S是一个集合,其中的每个元素表示一个顶点,从源点到这些顶点的最短距离已经求出。设顶点Vl为源点,集合S的初态只包含一个元素,即顶点5。数组dist记录从源点到其他顶点当前的最短距离,其初值为disti=costvi,i=l,2,no从S之外的顶点集合V-S中选出一个顶点w,使distw的值最小。于是从源点到达W只通过S中顶点,把W参加集合S中,调整dist中记录的从源点到V-S中每个顶点V的距离:从原来的distv和distw+costwv中选择较小的值作为新的distvo重复上述过程,直到V-S为空。最终结果是:S记录了从源点到该顶点存在最短路径的顶点集合,数组diSt记录了源点到V中其余各顶点之间的最短路径,Path是最短路径的路径数组,其中Pathi表示从源点到顶点i之间的最短路径的前驱顶点。因此,迪杰斯特拉算法可用自然语言描述如下:初始化S和D,置空最短路径终点集,置初始的最短路径值;Sv,=TRUE;Dv1=O;S集初始时只有源点,源点到源点的距离为0;While(S集中顶点数n)开始循环,每次求得巧到某个V顶点的最短路径,并加V到S集中;Sv=TRUE;更新当前最短路径及距离;3.2.3任意一对顶点间最短路径任意一对顶点间最短路径问题,是对于给定的有向网络图G=(V,E),要对G中任意一对顶点有序对"v,w(vw)",找出V到W的最短路径。要解决这个问题,我们可以依次把有向网络图中每个顶点作为源点,重复执行前面讨论的迪杰斯特拉算法n次,即可以求得每对顶点之间的最短路径。这里还可以用另外一种方法,称作费洛伊德(FIOyd)算法。费洛伊德(Floyd)算法算法的根本思想是:假设求从顶点Vi到Vj的最短路径。如果从V,到Vj存在一条长度为arcsij的路径,该路径不一定是最短路径,还需要进行n次试探。首先考虑路径V“V)和V,Vj是否存在。如果存在,那么比拟V,Vj和vbvbvj的路径长度,取长度较短者为当前所求得的最短路径。该路径是中间顶点序号不大于1的最短路径。其次,考虑从V,到VJ是否包含有顶点Vz为中间顶点的路径V“,V2,Vj,假设没有,那么说明从V,到V的当前最短路径就是前一步求出的;假设有,那么Vi,,V2,Vj可分解为Vi,V2和V2,,Vj,而这两条路径是前一次找到的中间顶点序号不大于1的最短路径,将这两条路径长度相加就得到路径Qi,V2,Vj的长度。将该长度与前一次中求出的从V,到V的中间顶点序号不大于1的最短路径比拟,取其长度较短者作为当前求得的从Vi到Vj的中间顶点序号不大于2的最短路径。依此类推,直到顶点V.参加当前从Vi到Vj的最短路径后,选出从Vi到Vj的中间顶点序号不大于n的最短路径为止。由于图G中顶点序号不大于n,所以Vi到V)的中间顶点序号不大于n的最短路径,已考虑了所有顶点作为中间顶点的可能性,因此,它就是Vi到VJ的最短路径。3.31设计功能的实现】3.3.1建立有向图的存储结构voidCreateMGraph(MGraph*G,intn,inte)构建城市的有向图inti,j,k,x;for(i=l;i<=n;i+)以任意城市i出发为起点G->vexsi=(char)i;for(i=l;i<=n;i+)for(j=l;j<=n;j+)任意城市j为终点G->arcsij=Maxint;距离初始化Printf("输入为d条边的i,j及x:n”,e);for(k=l;k<=e;k+)(scanf(zz%d,%d,',&i,&j,&x);G->arcsij=x;建立城市之间的距离)Printf(“城市的有向图存储结构建立完毕!n");3.3.2迪杰斯特拉算法voidDijkstra(MGraph*G,intvl,intn)迪杰斯特拉特拉算法求一个城市到任意一个城市的距离intD2Num,P2Num;intv,i,w,min;enumbooleanSNum;for(v=l;v<=n;v+)(Sv=FALSE;D2v=G->arcsvlv;if(D2v<Maxint)P2v=vl;elseP2v=0;s置空距离初始化/路径初始化P2vl=0jSvl=TRUE;for(i=2;i<n;i+)min=Maxint;for(w=l;w<=n;w+)if(!Sw&&D2w<min)(V=w;min=D2w;Sv=TRUE;for(w=l;w<=n;w+)/源点Vl放入s中循环直至所有顶点的最都求出/Maxint置最小长度初值选不在S中且有最小顶点w顶点W参加s中if(!Sw&&(D2Ev+G->arcsvw"D2w)修改不在S中的顶点的距离D2w=D2v+G->arcsvw;P2w=v;Printf("路径长度路径n");for(i=l;i<=n;i+)printf("%5d”,D2i);Printf("%5d”,i);v=P2i;while(v!=0)printf("<-,v);v=P2v;输出最短路径Printf("n");3.3.3费洛伊德算法voidFloyd(MGraph*G,intn)(inti,j,k;for(i=l;i<=n;i+)for(j=l;j<=n;j+)(if(G->arcsij!=Maxint)Pij=j;elsePij=O;Dij=G->arcsij;)for(k=l;k<=n;k+)用弗洛伊德算法求任意两顶点最短距离定义三个变量距离初始化路径初始化以k为源点循环求出所有顶点的最短路径for(i=l;i<=n;i+)i为最短路径的顶点for(j=l;j<=n;j+)/j为未知最短路径的顶点(if(Dik+Dkj<Dij)Dij=Dik+Dkj;Pij>Pik;printf(zzdij=%d,Pij=%dn”,Dij,Pij);3. 3.4运行主控程序#include<stdio.h>#include<stdlib.h>#defineNum300定义常量NUnlttdefineMaxint32767enumbooleanFALSE,TRUE);定义布尔型typedefcharVertexType;typedefintAdjmatrix;typedefstructVertexTypevexsNum;定义顶点AdjmatrixarcsNumNum;定义路径长度MGraph;intDlNum,PlNum;intDNumNum,PNumNum;voidCreateMGraph(MGraph*G,intn,inte);构建城市的有向图的声明voidDijkstra(MGraph*G,intvl,intn);迪杰斯特拉算法的声明voidFloyd(MGraph*G,intn);弗洛伊德算法的声明voidmain()(MGraph*G;定义有向图Gintn,e,v,w,k,min;inta=l;G=(MGraph*)malloc(sizeof(MGraph);Printf(输入图中顶点个数和边