Dijkstra算法修改版.docx
《Dijkstra算法修改版.docx》由会员分享,可在线阅读,更多相关《Dijkstra算法修改版.docx(10页珍藏版)》请在冰豆网上搜索。
![Dijkstra算法修改版.docx](https://file1.bdocx.com/fileroot1/2022-11/26/5dfbb35c-130f-4fb6-b248-8010128eb126/5dfbb35c-130f-4fb6-b248-8010128eb1261.gif)
Dijkstra算法修改版
课程设计报告
课程设计报告
课程
数据结构与算法
课程设计名称
Dijkstra算法
学生姓名
沈千行
学号
20096341
专业班级
数学学院09信息与计算科学1班
一、问题分析和任务定义
本次课程设计的题目如下:
选择合适的数据结构表示图,在此基础上实现求解最短路径的Dijkstra算法。
要求:
对所设计的图的数据结构提供必要的基本功能。
Dijkstra算法意思为,设从顶点v1出发,找从它到图中所有其它各顶点的最短路径。
迪杰斯特拉(Dijkstra)提出了一个按路径长度递增的顺序产生最短路径的方法。
把图中顶点集合分成两组,第一组为集合S,存放已求出其最短路径的顶点,第二组为尚未确定最短路径的顶点集合是V-S(用U表示),其中V为网中所有顶点集合。
按最短路径长度递增的顺序逐个把U中的顶点加到S中,直到S中包含全部顶点,而U为空。
在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。
此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。
算法分析:
我们可以将图中的顶点分为两组:
S——已求出的最短路径的终点集合(开始为{v0})
V-S——尚未求出最短路径的顶点集合(开始为V-{v0}的全部结点)。
按最短路径长度的递增顺序逐个将第二组的顶点加入到第一组中。
引进辅助向量dist[],它的每一个分量dist[i]表示已经找到的且从开始点v0到每一个终点vi的当前最短路径的长度。
它的初态为:
如果从v0到vi有弧,则dist[i]为弧的权值;否则,dist[i]为∞,即为MAX。
定义数组P[i][j]用来存放一个有向网产生的邻接矩阵。
Vi->Vj之间有弧的时候,P[i][j]=1。
Vi->Vj之间不存在弧的时候,P[i][j]=0。
于是产生一个n*n的方阵。
方便直观的让读者判断顶点i和顶点j是否有弧相连。
找下一条长度次短的路径。
假设该次短路径的终点是vk,则这条路径可能是(v0,vk)或者是(v0,vj,vk)。
二、概要设计和数据结构选择
用一维数组来存储顶点的信息,二维数组来存储边的信息,通过输入顶点和边的信息,最终将最短路径的结果保存在Dist[]数组中输出。
三、详细设计和编码
首先,定义网,其中包括对顶点的信息,顶点数,弧数的描述。
相关程序如下:
structMGraph//定义网
{
VertexDatavexs[MAX_V_N];
AdjMatrixarcs;
intvexnum,arcnum;
}
接下来编写定位函数,方便定位图中的顶点。
intLocateVex(MGraphG,VertexDatau)//定位
{
inti;
for(i=0;ireturn-1;
}
这些都是为了建立有向网作了基础,CreateDN建网函数中输入顶点数和弧数,并初始化弧的权值。
5
3
1050
10030
1020
60
程序的核心算法即为迪杰斯特拉算法,定义数组P[i][j]和dist[i]分别存放邻接矩阵和最短路径的长度。
S←{v0},dist[i]=g.arcs[v0][vi],将v0到其余顶点的路径长度初始化为权值。
a.比较dist[i],找到顶点vk,使得dist[k]=Min{dist[i]},i,k∈V;将vk并入S集,遍历过的顶点加入S集,并将S[v]=1。
b.比较与的大小,若dist[k]+g.arcs[k][i]重复a,b即可按最短路径长度的递增顺序,逐个求出v0到图中其它每个顶点的最短路径。
四、上机调试
开始时把一些整型的变量全部定义在循环体系中,使用C-Free编译时无法通过,然后把定义拿到循环外面,编译就通过实现了。
在图定位函数中,开始时我使用了if(G.vexs[i]==u)来判断是否存在这样的顶点,但编译时总是输出顶点V0到其他点都是无路。
后来我就把这句代码改动一下,利用字符串的比较来得出顶点是否存在。
五、用户说明
用户只需画出有向图,在依照程序运行后的文字提示,输入相应的顶点数,弧数。
在对应图输入起点,终点,以及权值。
运行后即可得出对应的邻接矩阵和最短路径长度。
六、测试结果
七、带注释的源程序
#include
#include
#include
#defineMAX_NAME10
#defineMAX_V_N26
#defineMAX32768
typedefcharVertexData[MAX_NAME];
typedefintAdjMatrix[MAX_V_N][MAX_V_N];//邻接距阵
structMGraph//定义网
{
VertexDatavexs[MAX_V_N];
AdjMatrixarcs;
intvexnum,arcnum;
};
intLocateVex(MGraphG,VertexDatau)//定位
{
inti;
for(i=0;ireturn-1;
}
voidCreateDN(MGraph&G)//建网
{
inti,j,k,weight;
VertexDatav1,v2;
printf("请输入有向网G的顶点数和弧数(以空格作为间隔)\n");
scanf("%d%d",&G.vexnum,&G.arcnum);
printf("请输入%d个顶点的值(<%d个字符):
\n",G.vexnum,MAX_NAME);
for(i=0;iscanf("%s",G.vexs[i]);
for(i=0;ifor(j=0;jG.arcs[i][j]=MAX;
printf("请输入%d条弧的弧尾弧头权值(以空格作为间隔):
\n",G.arcnum);
for(k=0;k{
scanf("%s%s%d%*c",v1,v2,&weight);
i=LocateVex(G,v1);
j=LocateVex(G,v2);
G.arcs[i][j]=weight;
}
}
typedefintPathMatrix[MAX_V_N][MAX_V_N];
typedefintShortPathTable[MAX_V_N];
voidShortestPath_DIJ(MGraphG,intv0,PathMatrixP,ShortPathTableDist)
{
intv,w,i,min;
ints[MAX_V_N];
for(v=0;v{
s[v]=0;
Dist[v]=G.arcs[v0][v];
for(w=0;wP[v][w]=0;
if(Dist[v]P[v0][v]=1;
}
Dist[v0]=0;
s[v0]=1;
for(i=1;i{
min=MAX;
for(w=0;wif(s[w]!
=1&&Dist[w]{
v=w;
min=Dist[w];
}
s[v]=1;
for(w=0;wif(s[w]!
=1&&min{
Dist[w]=min+G.arcs[v][w];
P[v][w]=1;
}
}
}
intmain()
{
inti,j;
MGraphg;
PathMatrixp;
ShortPathTabled;
CreateDN(g);
ShortestPath_DIJ(g,0,p,d);//以g中位置为0的顶点为源点,求其到其余各顶点的最短距离。
存于d中
printf("最短路径数组p[i][j]如下:
\n");
for(i=0;i{
for(j=0;jprintf("%2d",p[i][j]);
printf("\n");
}
printf("%s到各顶点的最短路径长度为:
\n",g.vexs[0]);
for(i=0;iif(i!
=0)
{
if(d[i]-MAX)printf("%s-%s:
%d\n",g.vexs[0],g.vexs[i],d[i]);
elseprintf("%s-%s:
无路\n",g.vexs[0],g.vexs[i]);
}
system("PAUSE");
return0;
}