单源最短路径SPFA.docVIP

  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文档。上传文档
查看更多
单源最短路径SPFA.doc

SPFA – Shortest Path Faster Algorithm,简单的说就是队列优化的Bellman-Ford算法,利用了每个点不会更新次数太多的特点发明了此算法. 它可以在O(kE)的时间复杂度内求出源点到其它所有点的最短路径,并且可以处理负权边. SPFA算法的实现甚至比Dijkstra或Bellman-Ford还要简单: ?????? 设Dist代表S到I点的当前最短距离,Fa代表S到I的当前最短路径中I点之前的一个点的编号. 开始时Dist全部为+∞,只有Dist[S]=0,Fa全部为0. ?????? 维护一个队列,里面存放所有需要进行迭代的点. 初始时队列中只有一个点S. 用一个布尔数组纪录每个点是否处在队列中. 每次迭代,取出队头的点v,依次枚举从v出发的边v-u,设边的长度为len,判断Dist[v]+len是否小于Dist,若小于则改进Dist,将Fa记为v,并且由于S到u的最短距离变小了,有可能u可以改进其它的点,所以若u不在队列中,就将它放入队尾. 这样一直迭代下去直到队列变空,也就是S到所有点的最短距离确定下来了,则算法结束. 若一个点入队次数超过n,则有负权环. ?????? SPFA在形式上和BFS(宽度优先搜索)非常类似,不同的是BFS中一个点出了队列就不可能重新进入队列,但是SPFA中一个点可能在出队列之后再次被放入队列,也就是一个点改进过其它的点之后,过了一段时间可能本身被改进,于是再次用来改进其它的点,这样反复迭代下去. 设一个点用来作为迭代点对其它点进行改进的平均次数为k,有办法证明对于通常的情况k在2左右. ? ?????? Dijkstra算法的效率高,但是也有局限性,就是对于含负权的图无能为力. ?????? Bellman-Ford算法对于所有最短路长存在的图都适用,但是效率常常不尽人意. ?????? SPFA算法可以说是综合了上述两者的优点. 它的效率同样很不错,而且对于最短路长存在的图都适用,无论是否存在负权边. 它的编程复杂度也很低,是性价比极高的算法. ?????? 在不含负权的图中,特别是在边数稠密的图中,我们常常选择Dijkstra算法; 在稀疏图中,二叉堆实现的Dijkstra算法也是不错的选择,SPFA算法效率极高; 在图中含有负权,稀疏图随便用后两种算法中的哪一种都行,因为它们的效率都可以接受,而且很容易写; 如果是稠密图,就非SPFA算法莫属了. Pascal伪代码: Procedure SPFA; Begin initialize-single-source(G,s); initialize-queue(Q); enqueue(Q,s); while not empty(Q) do begin u:=dequeue(Q); for each v∈adj[u] do begin tmp:=d[v]; relax(u,v); if (tmpd[v]) and (not v in Q) then enqueue(v); end; end; End; SPFA算法? 求单源最短路的SPFA算法的全称是:Shortest?Path?Faster?Algorithm。? 从名字我们就可以看出,这种算法在效率上一定有过人之处。? 很多时候,给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了。? 简洁起见,我们约定有向加权图G不存在负权回路,即最短路径一定存在。当然,我们可以在执行该算法前做一次拓扑排序,以判断是否存在负权回路,但这不是我们讨论的重点。? 和上文一样,我们用数组d记录每个结点的最短路径估计值,而且用邻接表来存储图G。我们采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。? 定理3?只要最短路径存在,上述SPFA算法必定能求出最小值。? 证明:每次将点放入队尾,都是经过松弛操作达到的。换言之,每次的优化将会有某个点v的最短路径估计值d[v]变小。所以算法的执行会使d越来越小。由于我们假定图中不存在负权回路,所以每个结点都有最短路径值。因此,算法不会无限执行下去,随着d值的逐渐变小,直到到达最短路径值时,算法结束,这时的最短路径估计值就是对应结点的最短路径值。(证毕)? 刚才我们只是笼统地说SPFA算法在效率上有过人之处,那么到底它的复杂度是怎样的?? 定理4?在平均情况下,SPFA算法的期望时间复杂度

文档评论(0)

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

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

1亿VIP精品文档

相关文档