05SPFA算法.pptVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
05SPFA算法

SPFA算法 SPFA 全称 Shortest Path Faster Algorithm 基本应用为快速求解单源最短路 Spfa算法可以说是beelman算法的改进版.spfa是利用队列来动态更新最小值. 它的工作方法是这样:每次取出队头的顶点K,对于所有与他相邻的点I,我们进行如下操作:判断从点K到点I的值是否当前的最小距离,如果是,则更新最小值,并且看看I是否在队列里,如果不在,则将点I加入队列.可以说,算法还是比较好理解的,spfa算法是属于那种标号修正法类的. SPFA算法实现 设Dist代表S到I点的当前最短距离,Fa代表S到I的当前最短路径中I点之前的一个点的编号。开始时Dist全部为+∞,只有Dist[S]=0,Fa全部为0。 维护一个队列,里面存放所有需要进行迭代的点。初始时队列中只有一个点S。用一个布尔数组记录每个点是否处在队列中。 SPFA算法实现 每次迭代,取出队头的点v,依次枚举从v出发的边v-u,设边的长度为len,判断Dist[v]+len是否小于Dist[u],若小于则改进Dist[u],将Fa[u]记为v,并且由于S到u的最短距离变小了,有可能u可以改进其它的点,所以若u不在队列中,就将它放入队尾。这样一直迭代下去直到队列变空,也就是S到所有的最短距离都确定下来,结束算法。若一个点入队次数超过n,则有负权环。 SPFA算法实现 SPFA 在形式上和宽度优先搜索非常类似,不同的是宽度优先搜索中一个点出了队列就不可能重新进入队列,但是SPFA中一个点可能在出队列之后再次被放入队列,也就是一个点改进过其它的点之后,过了一段时间可能本身被改进,于是再次用来改进其它的点,这样反复迭代下去。 伪代码描述: w[i,j]表示i,j的权 s[i,j]表示i到j的最短路 repeat for 所有边[i,j] if s[o,i]+w[i,j]s[o,j] then 更新s[o,j] until 没有改变 伪代码描述: 这种算法适用于所有类型的图(SSSP),如果要求任两个点的最短路径(APSP),则要重复n次 有几个优化: 1.可以先判断是否有负权自环,有则直接输出-1 2.在枚举的过程中,当这个顶点的最短路(d[i])0时,有负权回路,输出-1.   void spfa(int s)   {   int q[101],v[101],h=0,t=1,x,i; //q为队列,v为Boolean数组,表示结点是否在队列中,h为头指针,t为尾指针   memset(q,0,sizeof(q));   memset(v,0,sizeof(v));   for(i=0;i101;i++) dist[i] = INT_MAX; //这里应该用for循环初始化,memset函数只能将值初始化为0或者-1。   dist[s]=0;   q[t]=s;v[s]=1;   while(h!=t) { //本来是ht,但这不是循环队列么,不能这么干的...    h=(h+1)%(n+1);//这里不能%n否则队满和队空状态一样    x=q[h];    v[x]=0;    for(i=1;i=n;i++)    if(dist[i]-a[x][i]dist[x]) { //这里本来为dist[i]dist[x]+a[x][i],但这样会越界的,因为后两者加起来太大     dist[i]=dist[x]+a[x][i];    if(!v[i]) { t=(t+1)%(n+1)/*同上*/;q[t]=i;v[i]=1;  }   } } } Relax(u,v){ If (F(v)F(u)+W_Cost(u,v)) F(v)=F(u)+W_Cost (u,v); } SPFA的核心正是松弛操作: ....... A1 T An S 但松弛操作直接得出的Bellman-Ford算法效率低下 For Time=1 to N For (u,v)∈E Relax(u,v) 上图数据中,总运算量高达N^2 而边(S, A1)虽然被调用N次。 但实际有用的只有一次 SPFA则使用队列进行了优化! 思想: 只保存被更新但未扩展的节点。 减少了大量无用的计算,效率大大提高! A1 A2 ……. A4 An-1 A3 An Head Tail 当前待扩展元素 在上图的例子中,每个节点只进队一次,只需N次运算。 相比Bellman-Ford优势明显。 ....... A1 T An S 我们再从另一个角度来分析DIJ和sp

文档评论(0)

jiupshaieuk12 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

版权声明书
用户编号:6212135231000003

1亿VIP精品文档

相关文档