您的位置:首页 > 编程语言

最短路径实现代码-->Dijkstra求解最短路径问题

2012-07-31 12:53 676 查看
在求解最短路径问题上,Dijkstra的算法当属家喻户晓的经典,这种算法是贪婪算法。
问题描述:假设现在有一个有向图G,如图所示,每条边都有一个耗费值,路径的长度为路径所经过的边的耗费值之和。现在求s点,到其他任意顶点的最短路径。



算法原理:

假设所有的顶点集合为V。

首先把V分成两组:

(1)S:已求出最短路径的顶点的集合(如果从顶点s1出发,则集合S初始化只包含点s1)。

(2)V-S=T:尚未确定最短路径的顶点集合。

(3)使用一个数组d(d[i]表示集合S到达到达顶点i的距离),来记录从S集合到达各个顶点的距离。

(4)依据距离数组d的值,选择S能到达的距离最短的点加入S集合中,然后根据新加入的顶点v1所能到达的顶点来更新S集合到达各个顶点的距离,也就是更新距离数组d。当d[i]>d[v]+a[v][i]是更行d[i]=d[v]+a[v][i]。

(5)这样循环的执行(4),直到所有的点都在集合S中了,终止。d中记录S到达各个顶点的最短距离。

使用贪婪算法,每次都选择S所能到达的距离最近的顶点加入,则当所有点都加入S集合后,即得到了最短路径。

实现代码:

//a表示邻接矩阵,d存储到达第i个点的最短距离,
//p[i]存储到达i点的路径中i前面的那个点。n表示点的数目。
//-1表示两个点不存在直连边。s表示从s点出发
void StructApp::ShortestPaths(int **a,int* d,int *p,int s,int n)
{
list<int> dlist;//存储当前可达点
//从s点出发
for(int i=1;i<=n;i++)
{
d[i]=a[s][i];
if(a[s][i]!=-1)
{
p[i]=s;
dlist.push_back(i);
}
else
p[i]=0;
}
while(!dlist.empty())
{

list<int>::iterator dite=dlist.begin();
int v=*dite;
//从当前可达点中选择距离最短的点
for(++dite;dite!=dlist.end();++dite)
{
if(d[*dite]<d[v]||d[v]==-1)
v=*dite;
}
dlist.remove(v);
for(int i=1;i<=n;i++)
{
if(a[v][i]!=-1&&(!p[i]||d[i]>d[v]+a[v][i]||d[i]==-1))
{
d[i]=d[v]+a[v][i];
if(!p[i])
dlist.push_back(i);
p[i]=v;

}
}

}
}
void StructApp::PrintPaths(int *p,int* d,int s,int n)
{
for(int i=1;i<=n;i++)
{
OutputPaths(p,d,s,i,i);
cout<<endl;
}
}
//src表示起始点,des表示目标点,mid表示中间经过的点。
void StructApp::OutputPaths(int* p,int* d,int src,int mid,int des)
{
if(src==mid)
{
cout<<src<<"到"<<des<<"路径长度是:"<<d[des]<<"。路径为:"<<src;
return ;
}
OutputPaths(p,d,src,p[mid],des);
cout<<"->"<<mid;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: