单源最短路径.docx
- 文档编号:28714292
- 上传时间:2023-07-19
- 格式:DOCX
- 页数:14
- 大小:254.48KB
单源最短路径.docx
《单源最短路径.docx》由会员分享,可在线阅读,更多相关《单源最短路径.docx(14页珍藏版)》请在冰豆网上搜索。
单源最短路径
单源最短路径问题[Dijkstra实现]
一、问题
带权有向图G(E,V),找出从给定源顶点s到其它顶点v的权最小路径。
“最短路径”=最小权
二、问题求解:
求1到5的最短路径值?
三、执行过程:
如果大家对这个问题的要求还不是很明白的话那么我再带着大家走一遍:
第一次:
从1-->2:
10此时从1-->3没有路径所有是无穷大 1-->4:
30 1-->5:
100那么我们发现这一组组最小的是10也就是2这一点,所以我们再把2这一点加到集合里面来,那么2这一点就可以当作一个桥来用,
第二次:
此时我们再从1à3就可以通过1-->2-->3:
60其他的1-->4:
30
1-->5:
100可以发现此时最小的应该是3,所以我们再把3这一点加入到这个集合里面来,如此重复的去做这些事情,到最后可以发现1à5的最短路径应该是60(1-->4-->3-->5)
四、Dijkstra伪代码:
intdijkstra(ints,intt){
初始化S={空集}
d[s]=0;其余d值为正无穷大
while(NOTtinS)
{
取出不在S中的最小的d[i];
for(所有不在S中且与i相邻的点j)
if(d[j]>d[i]+cost[i][j])d[j]=d[i]+cost[i][j];(“松弛”操作”)
S=S+{i};//把i点添加到集合S里
}
returnd[t];
}
为何松弛操作:
也就是说如果1-->3这点的值为dist[3]>dist[2]+map[2][3]
那么dist[3]=dits[2]+map[2][3]
5、代码实现:
#include
usingnamespacestd;
#defineMAX9999999
#defineLEN210
intmap[LEN][LEN];//某点到某点两点间的的距离
intdist[LEN];//记录当前点到源点的最短路径长度
intmark[LEN];//加入进来的点的集合
//初始化map为正无穷大
voidinit(){
inti,j;
for(i=0;i for(j=0;j map[i][j]=MAX; } } } //n: 多少条路start: 起始点 voidmyDijstra(intn,intstart){ inti,j,min,k; for(i=1;i<=n;i++){ mark[i]=0;//没有点加入 dist[i]=map[start][i];//初始 } mark[start]=1;//把起始点加进来 dist[start]=0; for(i=1;i<=n;i++){ min=MAX; for(j=1;j<=n;j++){ if(! mark[j]&&dist[j] min=dist[j]; k=j;//标记 } } if(min==MAX) break; mark[k]=1;//把K加进来 //做松弛操作 for(j=1;j<=n;j++){ if(! mark[j]&&dist[j]>dist[k]+map[k][j]){ dist[j]=dist[k]+map[k][j]; } } } } intmain(){ inti,j,n,line; inta,b,d; cin>>n>>line;//输入点和边 init(); for(i=0;i cin>>a>>b>>d;//输入各边的权值 if(map[a][b]>d){ map[a][b]=map[b][a]=d; } } myDijstra(n,1);//调用方法 //输出1到5的最短路径 cout< return0; } Dijkstra算法(单源最短路径) 单源最短路径问题,即在图中求出给定顶点到其它任一顶点的最短路径。 在弄清楚如何求算单源最短路径问题之前,必须弄清楚最短路径的最优子结构性质。 一.最短路径的最优子结构性质 该性质描述为: 如果P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,k和s是这条路径上的一个中间顶点,那么P(k,s)必定是从k到s的最短路径。 下面证明该性质的正确性。 假设P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,则有P(i,j)=P(i,k)+P(k,s)+P(s,j)。 而P(k,s)不是从k到s的最短距离,那么必定存在另一条从k到s的最短路径P'(k,s),那么P'(i,j)=P(i,k)+P'(k,s)+P(s,j) 则与P(i,j)是从i到j的最短路径相矛盾。 因此该性质得证。 二.Dijkstra算法 由上述性质可知,如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点。 那么(Vi...Vk)也必定是从i到k的最短路径。 为了求出最短路径,Dijkstra就提出了以最短路径长度递增,逐次生成最短路径的算法。 譬如对于源顶点V0,首先选择其直接相邻的顶点中长度最短的顶点Vi,那么当前已知可得从V0到达Vj顶点的最短距离dist[j]=min{dist[j],dist[i]+matrix[i][j]}。 根据这种思路, 假设存在G= 1.从V-U中选择使dist[i]值最小的顶点i,将i加入到U中; 2.更新与i直接相邻顶点的dist值。 (dist[j]=min{dist[j],dist[i]+matrix[i][j]}) 3.知道U=V,停止。 /*Dijkstra求单源最短路径2010.8.26*/ #include #include #defineM100 #defineN100 usingnamespacestd; typedefstructnode { intmatrix[N][M];//邻接矩阵 intn;//顶点数 inte;//边数 }MGraph; voidDijkstraPath(MGraphg,int*dist,int*path,intv0)//v0表示源顶点 { inti,j,k; bool*visited=(bool*)malloc(sizeof(bool)*g.n); for(i=0;i { if(g.matrix[v0][i]>0&&i! =v0) { dist[i]=g.matrix[v0][i]; path[i]=v0;//path记录最短路径上从v0到i的前一个顶点 } else { dist[i]=INT_MAX;//若i不与v0直接相邻,则权值置为无穷大 path[i]=-1; } visited[i]=false; path[v0]=v0; dist[v0]=0; } visited[v0]=true; for(i=1;i { intmin=INT_MAX; intu; for(j=0;j { if(visited[j]==false&&dist[j] { min=dist[j]; u=j; } } visited[u]=true; for(k=0;k { if(visited[k]==false&&g.matrix[u][k]>0&&min+g.matrix[u][k] { dist[k]=min+g.matrix[u][k]; path[k]=u; } } } } voidshowPath(int*path,intv,intv0)//打印最短路径上的各个顶点 { stack intu=v; while(v! =v0) { s.push(v); v=path[v]; } s.push(v); while(! s.empty()) { cout< s.pop(); } } intmain(intargc,char*argv[]) { intn,e;//表示输入的顶点数和边数 while(cin>>n>>e&&e! =0) { inti,j; ints,t,w;//表示存在一条边s->t,权值为w MGraphg; intv0; int*dist=(int*)malloc(sizeof(int)*n); int*path=(int*)malloc(sizeof(int)*n); for(i=0;i for(j=0;j g.matrix[i][j]=0; g.n=n; g.e=e; for(i=0;i { cin>>s>>t>>w; g.matrix[s][t]=w; } cin>>v0;//输入源顶点 DijkstraPath(g,dist,path,v0); for(i=0;i { if(i! =v0) { showPath(path,i,v0); cout< } } } return0; } 自己总结: 其实Dijkstra算法是一个数学问题,算法是一个贪心算法,未被确定的最短路径处在一个不断更新的过程中,已经确定的最短路径不需更新,每次都是在已经确定的最短路径的基础上获取新的最短路径。 并且最先找到的最短路径越短,最后找到的最短路径越长,也就是说,确定的最短路径是一个递增的趋势。 这里需要明确的一个很重要的问题就是: 下一条最短路径只能有两种情况: 1.集合A=由已经产生的最短路径的终点再扩充一条边得到; 2.B=由源点直接到达目的节点。 在实际的运算中使用Min(A的最小值,B)作为下一条最短路径。 下面给出Dijkstra算法的图示:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单源最短 路径