1、Dijkstra算法修改版课程设计报告课程设计报告课程数据结构与算法课程设计名称Dijkstra算法学生姓名沈千行学号20096341专业班级数学学院09信息与计算科学1班一、 问题分析和任务定义本次课程设计的题目如下:选择合适的数据结构表示图,在此基础上实现求解最短路径的Dijkstra算法。要求:对所设计的图的数据结构提供必要的基本功能。Dijkstra算法意思为,设从顶点v1出发, 找从它到图中所有其它各顶点的最短路径。 迪杰斯特拉(Dijkstra)提出了一个按路径长度递增的顺序产生最短路径的方法。把图中顶点集合分成两组,第一组为集合S,存放已求出其最短路径的顶点,第二组为尚未确定最短
2、路径的顶点集合是V-S(用U表示),其中V为网中所有顶点集合。按最短路径长度递增的顺序逐个把U中的顶点加到S中,直到S中包含全部顶点,而U为空。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。 算法分析:我们可以将图中的顶点分为两组:S 已求出的最短路径的终点集合(开始为v0) V-S 尚未求出最短路径的顶点集合(开始为Vv0的全部结点)。按最短路径长度的递增顺序逐个将第二组的顶点加入到第一组中
3、。引进辅助向量dist ,它的每一个分量disti表示已经找到的且从开始点v0到每一个终点vi 的当前最短路径的长度。 它的初态为:如果从v0到vi 有弧,则disti 为弧的权值;否则,disti 为 ,即为MAX。定义数组Pij用来存放一个有向网产生的邻接矩阵。Vi-Vj之间有弧的时候,Pij=1。Vi-Vj之间不存在弧的时候,Pij=0。于是产生一个n*n的方阵。方便直观的让读者判断顶点i 和顶点j 是否有弧相连。找下一条长度次短的路径。假设该次短路径的终点是vk,则这条路径可能是(v0 , vk) 或者是(v0 , vj , vk)。二、概要设计和数据结构选择用一维数组来存储顶点的信息
4、,二维数组来存储边的信息,通过输入顶点和边的信息,最终将最短路径的结果保存在Dist数组中输出。三、详细设计和编码首先,定义网,其中包括对顶点的信息,顶点数,弧数的描述。相关程序如下:struct MGraph/定义网VertexData vexsMAX_V_N;AdjMatrix arcs;int vexnum,arcnum;接下来编写定位函数,方便定位图中的顶点。int LocateVex(MGraph G,VertexData u)/定位int i;for(i=0;iG.vexnum;+i)if(strcmp(u,G.vexsi)=0)return i;return -1;这些都是为了建
5、立有向网作了基础,CreateDN建网函数中输入顶点数和弧数,并初始化弧的权值。 5 3 10 50 100 30 10 20 60 程序的核心算法即为迪杰斯特拉算法,定义数组Pij和disti分别存放邻接矩阵和最短路径的长度。Sv0 , disti= g.arcsv0vi, 将v0到其余顶点的路径长度初始化为权值。a.比较disti,找到顶点vk,使得distk = Mindisti, i , kV;将vk并入S集,遍历过的顶点加入S集,并将Sv=1。b.比较与的大小,若distk+g.arcskidisti,则将disti修改为 distk+ g.arcski ,将顶点间有权值的边Pij=
6、1,产生邻接矩阵。重复a,b即可按最短路径长度的递增顺序,逐个求出v0到图中其它每个顶点的最短路径。 四、上机调试开始时把一些整型的变量全部定义在循环体系中,使用C-Free编译时无法通过,然后把定义拿到循环外面,编译就通过实现了。在图定位函数中,开始时我使用了if(G.vexsi=u)来判断是否存在这样的顶点,但编译时总是输出顶点V0到其他点都是无路。后来我就把这句代码改动一下,利用字符串的比较来得出顶点是否存在。 五、用户说明用户只需画出有向图,在依照程序运行后的文字提示,输入相应的顶点数,弧数。在对应图输入起点,终点,以及权值。运行后即可得出对应的邻接矩阵和最短路径长度。六、测试结果七、
7、带注释的源程序#include#include#include#define MAX_NAME 10#define MAX_V_N 26#define MAX 32768typedef char VertexDataMAX_NAME;typedef int AdjMatrixMAX_V_NMAX_V_N;/邻接距阵struct MGraph/定义网VertexData vexsMAX_V_N;AdjMatrix arcs;int vexnum,arcnum;int LocateVex(MGraph G,VertexData u)/定位int i;for(i=0;iG.vexnum;+i)if(
8、strcmp(u,G.vexsi)=0)return i;return -1;void CreateDN(MGraph &G)/建网int i,j,k,weight;VertexData v1,v2;printf(请输入有向网G的顶点数和弧数(以空格作为间隔)n);scanf(%d %d,&G.vexnum,&G.arcnum);printf(请输入%d个顶点的值(%d个字符):n,G.vexnum,MAX_NAME);for(i=0;iG.vexnum;+i)scanf(%s,G.vexsi);for(i=0;iG.vexnum;+i)for(j=0;jG.vexnum;+j)G.arcsi
9、j=MAX;printf(请输入%d条弧的弧尾 弧头 权值(以空格作为间隔): n,G.arcnum);for(k=0;kG.arcnum;+k)scanf(%s%s%d%*c,v1,v2,&weight);i=LocateVex(G,v1);j=LocateVex(G,v2);G.arcsij=weight;typedef int PathMatrixMAX_V_NMAX_V_N;typedef int ShortPathTableMAX_V_N;void ShortestPath_DIJ(MGraph G,int v0,PathMatrix P,ShortPathTable Dist)in
10、t v,w,i,min;int sMAX_V_N;for(v=0;vG.vexnum;+v)sv=0;Distv=G.arcsv0v;for(w=0;wG.vexnum;+w)Pvw=0;if(DistvMAX)Pv0v=1;Distv0=0;sv0=1;for(i=1;iG.vexnum;+i)min=MAX;for(w=0;wG.vexnum;+w)if(sw!=1&Distwmin)v=w;min=Distw;sv=1;for(w=0;wG.vexnum;+w)if(sw!=1&minMAX&G.arcsvwMAX&(min+G.arcsvwDistw)Distw=min+G.arcsv
11、w;Pvw=1;int main()int i,j;MGraph g;PathMatrix p;ShortPathTable d;CreateDN(g);ShortestPath_DIJ(g,0,p,d);/以g中位置为0的顶点为源点,求其到其余各顶点的最短距离。存于d中printf(最短路径数组pij如下:n);for(i=0;ig.vexnum;+i)for(j=0;jg.vexnum;+j)printf(%2d,pij);printf(n);printf(%s到各顶点的最短路径长度为:n,g.vexs0);for(i=0;ig.vexnum;+i)if(i!=0)if(di-MAX)printf(%s-%s:%dn,g.vexs0,g.vexsi,di);else printf(%s-%s:无路n,g.vexs0,g.vexsi);system(PAUSE);return 0;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1