校园导游作业中最短路径算法
本程序采用的是Dijkstra算法以解决求取最短路径问题。
校园导游的课程作业里要求求两个地点间的最短路径,我使用了Dijkstra算法来解决这个问题。
该算法的基本思想为:把图中所有顶点分成两组,第一组包括已确定最短路径的顶点(初始只包括V0),第二组包括尚未确定最短路径的顶点,然后按最短路径长度递增的次序逐个把第二组的顶点加到第一组中去,直到从V0出发可以到达的所有顶点都包括到第一组中。
在这个过程中,总保持从V0到第一组的各个顶点最短路径长度都不大于从V0到第二组的任何顶点的最短路径长度。另外每一个顶点都对应一个距离值,第一组的顶点对应的距离值就是从V0到此顶点的只包括第一组的顶点为中间顶点的最短路径长度【1】。
为了解释得更清楚,如图(a)所示我们设有向图G有6个顶点(V0为源点),其存储结构用邻接矩阵表示(同本程序)。实现上面所描述的算法需要设置三个数组s[6]、dist[6]和path[6]。
数组s用来标记那些已经找到最短路径的顶点,若s[i]=1,则表示已经找到源点到顶点Vi的最短路径;若s[i]=0,则表示尚未求得从源点到顶点Vi的最短路径。数组初值s[0]=1,s[i]=0{i=1,2,3,4,5},即只有V0找到最短路径。
dist[i]=G.arcs【0][1] (这里似乎有bug) {i=1,2,3,4,5}。
path数组用于存放最短路径,其中path[i]表示从源点V0到顶点Vi之间最短路径上的前驱顶点,若从V0到Vi无路径,则path[i]=-1。以下求解最短路径。
第一步:初始化顶点V0到其余各点的路径长度,dist[i]={0,∞,10,∞,30,100}。从中选取最小的顶点V2,且s[2]=1,path[2]=0,如图(b)所示
第二步:找到顶点V2后,观察从“源点”经过“顶点V2”到“各个顶点”的路径长度是否比第一步所找到的要小(即观察s[i]=0的点),可发现,从源点到V3的值为60<∞,更新为dist[i]={0,∞,10,60,30,100},path[3]=2其他路径则不变。这时候从已更新的路径dist中找到最小的顶点V4,且更新数组s[4]=1。如图(c)所示。
第三步:找到顶点V4以后,再观察从源点经顶点V4到各顶点的路径是否比第二步所找到的路径要小,即与第二步相同。通过比较,源点到顶点V3的长度更新为50,path[3]=4;源点到顶点V5的路径长度更新为90,path[5]=4;dist[i]={0,∞,10,50,30,90}。这时候从已更新的路径dist中找到最小的顶点V3,且更新数组s[3]=1。如图(d)所示。
第四步:找到顶点V3后,再观察从源点经过顶点V3到各顶点的路径是否比上一步所找的路径要小,通过比较,源点到顶点V5的路径长度更新为60,path[5]=3,其余路径不变,dist[i]={0,∞,10,50,30,60}。然后通过已更新的路径中找到路径长度最小的顶点V5,且更新数组s[5]=1。如图(e)所示。
第五步:找到顶点V5后,再观察从源点经过顶点V5到各顶点的路径是否比上一步所找的路径要小,
通过比较路径不变。此时从源点到其余各点的最短路径已经求出如图(f)所示,有:
dist[i]={0,∞,10,50,30,60}
path[0]=-1,path[1]=-1,path[2]=0,path[3]=4,path[4]=0,path[5]=3。
s[0]=1,s[1]=0,s[2]=1,s[3]=1,s[4]=1,s[5]=1。
分析得到V0出发到其余各顶点的最短路径和路径长度为:
V0→V1:无路径
V0→V2:10
V0→V3:50(V0→V4→V3)
V0→V4:30
V0→V5:60(V0→V4→V3→V5)
以上就是Dijkstra算法的使用过程
本程序实现最短路径算法代码如下所示:
void Dijkstra(MGraph g,int origin,int terminal,int path[],int s[],float distance[])
{
//起始点origin到终点terminal的最短路径
//path[]是origin到terminal最短路径上的前驱节点
//distance[]是路径长度
//s[]用来标记已经找到最短路径的节点,若值为1表示已求得,0反之
for(int i=0;i<=g.vexnum-1;i++)
{
s[i]=0; //初始为0包括origin
distance[i]=g.arcs[origin][i]; //初始化distance
if(distance[i]<INF)
path[i]=origin; //初始化path
else
path[i]=-1; //给path[]赋值
}
distance[origin]=0; //初始化origin
s[origin]=1;
for(int j=0;j<=g.vexnum-1;j++)
{
int min=INF; //定义min从已更新的路径中找到路径长度最小的顶点
int x=0;
for(int n=0;n<=g.vexnum-1;n++)
{
if(!s[n]&&distance[n]<min) //判定是否已找出最短路径且路径存在
{
x=n;
min=distance[n];
}
}
s[x]=1; //将顶点x加入S[],此节点已经找到最短路径,1是找到标志
for(int k=0;k<=g.vexnum-1;k++)
{
if(!s[k]&&(min+g.arcs[x][k]<distance[k])) //更新路径,以及距离
{
distance[k]=min+g.arcs[x][k];
path[k]=x;
}
}
}
}
一些说明:
这是我的作业的一个笔记,上面内容是实验报告word文档直接复制粘贴下来的,其中的内容我也参考引用了一些课本上的内容。
[1]杨剑.数据结构.北京:清华大学出版社,2011年2月第1版
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。