ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:18.87KB ,
资源ID:10279194      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/10279194.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(求单源最短路SPFA算法.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

求单源最短路SPFA算法.docx

1、求单源最短路SPFA算法求单源最短路-SPFA算法求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm。 SPFA算法是西南交通大学段凡丁于1994年发表的.从名字我们就可以看出,这种算法在效率上一定有过人之处。 很多时候,给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了。 简洁起见,我们约定有向加权图G不存在负权回路,即最短路径一定存在。当然,我们可以在执行该算法前做一次拓扑排序,以判断是否存在负权回路,但这不是我们讨论的重点。 我们用数组d记录每个结点的最短

2、路径估计值,而且用邻接表来存储图G。我们采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。 定理: 只要最短路径存在,上述SPFA算法必定能求出最小值。 证明:每次将点放入队尾,都是经过松弛操作达到的。换言之,每次的优化将会有某个点v的最短路径估计值dv变小。所以算法的执行会使d越来越小。由于我们假定图中不存在负权回路,所以每个结点都有最短路径值。因此,

3、算法不会无限执行下去,随着d值的逐渐变小,直到到达最短路径值时,算法结束,这时的最短路径估计值就是对应结点的最短路径值。(证毕) 期望的时间复杂度O(ke), 其中k为所有顶点进队的平均次数,可以证明k一般小于等于2。实现方法:建立一个队列,初始时队列里只有起始点,再建立一个表格记录起始点到所有点的最短路径(该表格的初始值要赋为极大值,该点到他本身的路径赋为0)。然后执行松弛操作,用队列里有的点去刷新起始点到所有点的最短路,如果刷新成功且被刷新点不在队列中则把该点加入到队列最后。重复执行直到队列为空判断有无负环:如果某个点进入队列的次数超过N次则存在负环(SPFA无法处理带负环的图) 编辑本段

4、伪代码SPFA实际上是Bellman-Ford基础上的优化SPFA(G,w,s) 1. INITIALIZE-SINGLE-SOURCE(G,s) 2. INITIALIZE-QUEUE(Q) 3. ENQUEUE(Q,s) 4. While Not EMPTY(Q) 5. Do u-DLQUEUE(Q) 6. For 每条边(u,v) in EG 7. Do tmp-dv 8. Relax(u,v,w) 9. If (dv tmp) and (v不在Q中) 10. ENQUEUE(Q,v) 一种更容易读懂的伪代码Procedure SPFA;Begininitialize-single-so

5、urce(G,s);initialize-queue(Q);enqueue(Q,s);while not empty(Q) do beginu:=dequeue(Q);for each vadju do begintmp:=dv;relax(u,v);if (tmpdv) and (not v in Q) then enqueue(Q,v);end;end;End;期望的时间复杂度O(2e) 对spfa的一个很直观的理解就是由无权图的bfs转化而来.在无权图中,bfs首先到达的顶点所经历的路径一定是最短路(也就是经过的最少顶点数).所以此时利用visitu,可以使每个顶点只进队一次.在带权图中

6、,最先到达的顶点所计算出来的路径不一定是最短路.一个解决方法是放弃visit数组,此时所需时间自然就是指数级的.所以我们不能放弃visit数组,而是在处理一个已经在队列中且当前所得的路径比原来更好的顶点时,直接更新最优解. 编辑本段标准SPFA过程(以求某个结点t到某个结点s的最短路为例,稍加修改即为单源最短路)program spfaprg; Pascal代码const maxp=10000; 最大结点数var 变量定义p,c,s,t:longint; p,结点数;c,边数;s:起点;t:终点a,b:array1.maxp,0.maxp of longint; ax,y存x,y之间边的权;b

7、x,c存与x相连的第c个边的另一个结点yd:array1.maxp of integer; 队列v:array1.maxp of boolean; 是否入队的标记dist:array1.maxp of longint; 到起点的最短路head,tail:longint; 队首/队尾指针procedure init;vari,x,y,z:longint;beginread(p,c); for i := 1 to c dobeginreadln(x,y,z); x,y:一条边的两个结点;z:这条边的权值inc(bx,0); bx,bx,0 := y; ax,y := z; bx,0:以x为一个结点

8、的边的条数inc(by,0); by,by,0 := x; ay,x := z;end;readln(s,t); 读入起点与终点end;procedure spfa(s:longint); SPFAvari,j,now,sum:longint;beginfillchar(d,sizeof(d),0);fillchar(v,sizeof(v),false);for j := 1 to p do dist j :=maxlongint;dists := 0; vs := true; d1 := s; 队列的初始状态,s为起点head := 1; tail := 1;while headdistno

9、w+anow,bnow,i thenbegindistbnow,i:= distnow+anow,bnow,i; 修改最短路if not vbnow,i then 扩展结点入队begininc(tail);dtail := bnow,i;vbnow,i := true;end;end;vnow := false; 释放结点inc(head); 出队end;end;procedure print;beginwriteln(distt);end;begininit;spfa(s);print;end. C语言代码#include#define maxint 2139062143int a10110

10、1,dist101,n;void spfa(int s)int q101,v101,h=0,t=1,x,i;/q为队列,v为Boolean数组,表示结点是否在队列中,h为头指针,t为尾指针memset(q,0,sizeof(q);memset(v,0,sizeof(v);memset(dist,127,sizeof(dist);/置dist数组为maxint(+),下同dists=0;qt=s;vs=1;while(ht)h=(h+1)%n;x=qh;vx=0;for(i=1;idistx+axi)disti=distx+axi;if(!vi)t=(t+1)%n;qt=i;vi=1;int m

11、ain()int m,s,t,i;scanf(%d%d,&n,&m);scanf(%d%d,&s,&t);memset(a,127,sizeof(a);for(i=1;i=m;i+)int x,y,z;scanf(%d%d%d,&x,&y,&z);axy=z;ayx=z;spfa(s);printf(%d,distt);system(pause);return 0; 编辑本段SPFA的各种实现 最基本的前项性优化的spfa(有向图)复杂度O(ke).vara,b,e:array1.1000 of longint;vis:array1.2000 of boolean;q,d,f:array1.2

12、001 of longint;n,m,i,s,t:longint;procedure qsort(l,r:longint);var i,j,x,y:longint;begini:=l;j:=r;x:=a(l+r) shr 1;repeatwhile aix do dec(j);if not(ij) then beginy:=ai; ai:=aj; aj:=y;y:=bi; bi:=bj; bj:=y;y:=ei; ei:=ej; ej:=y;inc(i);dec(j);end;until ij;if ir then qsort(i,r);if lj then qsort(l,j);end;pr

13、ocedure spfa(s:longint);var i,k,l,t:longint;beginfillchar(vis,sizeof(vis),0);for i:=1 to n do di:=maxlongint;ds:=0;l:=0;t:=1;q1:=s;viss:=true;repeatl:=l mod 10000 +1;k:=ql;for i:=fk to fk+1-1 doif dk+eidbi thenbegindbi:=dk+ei;if not visbi then begint:=t mod 10000 +1;qt:=bi;visbi:=true;end;end;visk:=

14、false;until l=t;end;Beginreadln(n,m);for i:=1 to m doreadln(ai,bi,ei);qsort(1,m);for i:=1 to m doif fai=0 then fai:=i;fn+1:=m+1;for i:=n downto 1 doif fi=0 then fi:=fi+1;readln(s,t);spfa(s);writeln(dt);end. 堆排实现(无向图)const MM=1000;vara,b,e:array1.MM of longint;q,d,f:array1.2*MM+1 of longint;vis:array

15、1.MM of boolean;n,m,i,s,t:longint;mh:longint;procedure heapify(i:longint);var l,r,max,temp:longint;beginl:=2*i;r:=l+1;max:=i;if (lamax) then max:=l;if (ramax) then max:=r;if maxi then begintemp:=ai; ai:=amax; amax:=temp;temp:=bi; bi:=bmax; bmax:=temp;temp:=ei; ei:=emax; emax:=temp;heapify(max);end;e

16、nd;procedure heap;var i,temp:longint;beginmh:=m;for i:=(m div 2) downto 1 do heapify(i);for i:=m downto 2 do begintemp:=ai; ai:=a1; a1:=temp;temp:=bi; bi:=b1; b1:=temp;temp:=ei; ei:=e1; e1:=temp;dec(mh);heapify(1);end;end;procedure spfa(s:longint);var i,k,l,t:longint;beginfillchar(vis,sizeof(vis),fa

17、lse);for i:=1 to n do di:=maxlongint;ds:=0;l:=0;t:=1;viss:=true;q1:=s;repeatl:=(l mod (2*MM) +1;k:=ql;for i:=fk to fk+1-1 doif dk+eidbi thenbegindbi:=dk+ei;if not visbi then begint:=(t mod (2*MM) +1;qt:=bi;visbi:=true;end;end;visk:=false;until l=t;end;Beginreadln(n,m);for i:=1 to m do beginreadln(ai

18、,bi,ei);ai+m:=bi;bi+m:=ai;ei+m:=ei;end;m:=m+m;heap;for i:=1 to m do if fai=0 then fai:=i;fn+1:=m+1;for i:=n downto 1 do if fi=0 then fi:=fi+1;readln(s,t);spfa(s);writeln(dt);end. 邻接矩阵(无向图)以上两种是边集数组储存方式,以下是邻接矩阵(无向图):const MM=100*2;varn,m,i,j:longint;g:array1.MM,1.MM of longint;q,d:array1.MM of longin

19、t;vis:array1.MM of boolean;a,b,e,s,t:longint;procedure spfa(s:longint);var l,t,i,k:longint;beginfillchar(vis,sizeof(vis),false);for i:=1 to n do di:=maxlongint;ds:=0;l:=0;t:=1;q1:=s;viss:=true;repeatl:=l mod MM +1;k:=ql;for i:=1 to n doif (gk,imaxlongint)and(dk+gk,idi) then begindi:=dk+gk,i;if not visi then begint:=t mod MM +1;qt:=i;visi:=true;end;end;visk:=false;until l=t;end;beginreadln(n,m);for i:=1 to n dofor j:=1 to n do gi,j:=maxlongint;for i:=1 to m dobeginreadln(a,b,e);ga,b:=e;gb,a:=e;end;readln(s,t);spfa(s);writeln(dt);end.扩展阅读: 1. 2.

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1