Bellman-Ford算法及其队列优化(SPFA)

SPFA算法详解 单源最短路算法 Bellman-Ford队列优化 SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环。SPFA 最坏情况下复杂度和朴素 Bellman-Ford 相同,为 O(VE)。 SPFA算法的全称是:Shortest Path Faster Algorithm,是西南交通大学段凡丁于 1994 年发表的论文中的名字。不过,段凡丁的证明是错误的,且在 Bellman-Ford 算法提出后不久(1957 年)已有队列优化内容,所以国际上不承认 SPFA 算法是段凡丁提出的。 SPFA. 阅读详情

一、算法概述

        Bellman-Ford算法解决的是一般情况下的单源最短路径问题。所谓单源最短路径问题:给定一个图G=(V,E),我们希望找到从给定源结点s属于V到每个结点v属于V的最短路径。单源最短路径问题可以用来解决许多其他问题,其中包括下面几个最短路径的变体问题。包括单目的最短路径问题、单结点最短路径问题、所有结点对最短路径问题,这里不详细介绍。回到bellman-Ford,在这里,边的权重可以为负值。给定带权重的有向图G=(V,E)和权重函数W : E-->R,Bellman-Ford算法返回一个布尔值,以表明是否存在一个从源点可以到达的权重为负值的环路。如果存在这样的环路,算法将告诉我们不存在解决方案。如果没有这种环路存在,算法将给出最短路径和它们的权重。边的权值可以为负数、实现简单,缺点是时间复杂度过高,高达O(VE)。但算法可以进行若干种优化,提高了效率。

     自然语言描述

对有向图G(V,E),用贝尔曼-福特算法求以V_s为源点的最短路径的过程:

  • 建立dist[],表示目前已知源点到各个节点的最短距离,起始值dist[s]=0,其余皆为\infty。
  • 建立Pred[],Pred[]表示某节点路径上的父节点,起始值皆为NULL。
  • 对(V_i,V_j) \in E,比较dist[V_i]+(V_i,V_j)和dist[V_j],并将小的赋给dist[V_j],如果修改了dist[V_j]则pred[V_j]=V_i(松弛操作)
  • 重复以上操作V-1次
  • 再重复操作一次,如dist[V_j]>dist[V_i]+(V_i,V_j),则此图存在负权环。

    伪代码表示

BellmanFord(G,s)
 for i = 0 to n-1 do
  dist[i]= ∞
  Pred[i]= 0
 dist[s]=0
 for k = 1 to n-1 do
    foreach (V_i,V_j)∈E do
      if dist[V_i]+(V_i,V_j)<dist[V_j] do
          dist[V_j]=dist[V_i]+(V_i,V_j)
         Pred[V_j]=V_i
foreach (V_i,V_j)∈E do
      if dist[V_i]+(V_i,V_j)<dist[V_j] do
         return "No Shortest Path"
 return dist[]

二、原理

       为什么说最短路径不存在负环呢?

       如果图G包含从s可以达到的权重为负值的环路,则最短路径权重无定义。从s到该环路上的任意结点的路径都不可能是最短路径,因为我们只要沿着任何“最短”路径再遍历一次权重为负值的环路,则总是可以找到一条权重更小的路径。如果从结点s到结点v的某条路径上存在权重为负值的环路,我们定义s到v的最短路径等于负无穷。

        松弛操作

        它的原理是对图进行V-1次松弛操作,得到所有可能的最短路径。对于一条边(u,v)的松弛过程为:首先测试一下是否可以对源点s到v的最短路径进行改善。测试的方法是,将从结点s到结点u之间的最短路径距离加上结点u与v之间的权重,并与当前的s到v的最短路径估计进行比较,如果前者更小,则对v.d(源点s到v的最短路径) 和v.π(前驱结点)进行更新。

        每次松弛操作实际上是对相邻节点的访问,第n次松弛操作保证了所有深度为n的路径最短。由于图的最短路径最长不会经过超过V-1条边,所以可知贝尔曼-福特算法所得为最短路径。

        负边权操作

        与迪科斯彻算法不同的是,迪科斯彻算法的基本操作“拓展”是在深度上寻路,用于有向无环图的最短路径算法对每条边仅松弛一次。Bellman-Ford“松弛”操作则是在广度上寻路,这就确定了贝尔曼-福特算法可以对负边进行操作而不会影响结果。

       负权环判定

        因为负权环可以无限制的降低总花费,所以如果发现第n次操作仍可降低花销,就一定存在负权环。

三、队列优化——SPFA

       求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm。松弛操作必定只会发生在最短路径前导节点松弛成功过的节点上,用一个队列记录松弛过的节点,可以避免了冗余计算。复杂度可以降低到O(kE),k是个比较小的系数(并且在绝大多数的图中,k<=2,然而在一些精心构造的图中可能会上升到很高)

       实现方法:建立一个队列,初始时 里只有起始点,再建立一个表格记录起始点到所有点的最短路径(该表格的初始值要赋为极大值,该点到他本身的路径赋为0)。然后执行松弛操作,用队列里有的点去刷新起始点到所有点的最短路,如果刷新成功且被刷新点不在队列中则把该点加入到队列最后。重复执行直到队列为空
      判断有无负环:如果某个点进入队列的次数超过N次则存在负环 (存在负环则无最短路径,如果有负环则会无限松弛,而一个带n个点的图至多松弛n-1次 。

参考:算法导论、http://zh.wikipedia.org/zh-cn/%E8%B4%9D%E5%B0%94%E6%9B%BC-%E7%A6%8F%E7%89%B9%E7%AE%97%E6%B3%95#.E6.9D.BE.E5.BC.9B

Unity类银河战士恶魔城学习总结(P103之前 Enemy相关 , 骷髅战士,状态机,敌人状态,) udemy的Alex银河战士恶魔城,记录我自己的学习,代码会逐渐每一p更新,仅供参考学习。 阅读详情

相关推荐

4.2 结构翻模

结构翻模功能可以将DWG文件中的二维图线对象:轴网、墙、柱、梁、基础、房间和面积等快速转换成Revit模型对象,翻模速度快,准确率高。与先前的模盒翻模功能不同,结构翻模不再需要在AutoCAD中提取模型的图线,所有操作在Revit均可完成。(1)翻模程序适用于钢筋混凝土结构的平法DWG文件。(2)将平法中所表示的轴网线,轴网文字,结构柱,梁,结构墙在Revit 中重新建出来。(3) 模盒可以翻出连...

fishbuaa的专栏 1796

Bellman-Ford(单源最短路径)——队列优化

Bellman-Ford(单源最短路径)——队列优化 初始时将源点加入队列。每次从队首取出一个顶点,并对与其相邻的所有顶点进行松弛操作,若某个相邻的顶点松弛成功且这个相邻的顶点不在队列中,则对当前顶点处理完毕后立即出队,并对新的队首元素进行如上操作,直到队列为空时算法结束。

qq_44423388的博客 1006

工创赛智能搬运小车实战:视觉定位、底盘控制与RTOS调度

智能搬运系统是嵌入式控制与机器视觉融合的典型工程实践,其核心在于视觉定位精度、运动控制稳定性与实时任务调度能力。在有限算力(如STM32H7)、低功耗约束和结构化场景下,传统CV方法(如FAST+RANSAC)比轻量级深度学习更具鲁棒性与实时性;而底盘控制需穿透PID表层,直击死区补偿、编码器硬件滤波与负载自适应等物理层细节;RTOS则不是炫技工具,而是保障多模块时序确定性的刚需——尤其在视觉-控制-执行强耦合链路中,任务优先级、事件组通信与栈安全直接影响系统存活。本文聚焦全国大学生工程训练竞赛(工创赛)真

weixin_29194693的博客 267

Bellman-Ford算法,Bellman-Ford队列优化(SPFA)

但是如果有负权回路的话每次更新的时候边都会变小因此bellman-ford算法无法求解具有负权回路的问题,但是bellman-ford可以判断是否存在负权回路。但是Bellman-Ford可以判断是否可以存在负环,同样的SPFA也可以判断负环的存在。然后让入队的点在下面去更新后面的点,如果一个点已经在队列中则不需要进行二次入队。Bellman-Ford算法能解决负权的问题但不能解决负权回路的问题。spfa算法是对bellman-ford算法进行的队列优化。floyd算法使用的是动态规划的思想。

m0_62909934的博客 496

HAL库STM32CubeMX+DHT11温湿度传感器模块化驱动与OLED显示实战

本文详细介绍了基于HAL库和STM32CubeMX开发DHT11温湿度传感器模块化驱动的实战过程。通过精确的时序控制和模块化封装,实现了传感器数据采集,并结合OLED显示模块实时展示温湿度信息,为嵌入式开发者提供了完整的解决方案。

h6j7k8l9p0的博客 1134

VSCode里玩转AvaloniaUI:手把手教你搭建跨平台桌面应用开发环境(附.NET 7配置避坑)

本文详细介绍了如何在VSCode中搭建AvaloniaUI跨平台桌面应用开发环境,包括.NET 7配置避坑指南。从环境准备、项目创建到调试优化,手把手教你利用VSCode和Avalonia实现高效开发,特别解决了.NET 7依赖等常见问题,助力开发者快速上手跨平台应用开发。

weixin_28826545的博客 577

单源最短路算法—Bellman-Ford

Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法。该算法由Richard Bellman 和 Lester Ford 分别发表于 1958 年和 1956 年,而实际上 Edward F. Moore 也在 1957 年发布了相同的算法,因此,此算法也常被称为 Bellman-Ford-Moore 算法...

微凉的博客 336

FPGA—ZYNQ_BD Block Design学习(一)

1.第一步:打开Vivado软件,创建或打开一个工程。2.第二步:在Block Design中添加arm核心,并将其配置为IP核。3.第三步:配置arm核心的外设信息,如DDR接口、时钟频率、UART接口等。4.第四步:完成Block Design中的模块互联,生成PL端的比特流。 5.第五步:导出PS端的硬件信息,包括arm IP核的外设、速度、引脚和地址等信息。1创建bd 需要有ddr以及uart和时钟配置外设io口,这里就是zynq的管脚规定好的,根据原理图用哪个个勾选哪一个。 对外设uart的配

m0_58129662的博客 1028

Bellman-Ford算法(含队列优化)

Bellman-Ford算法 之前我已经介绍过Dijkstra算法,Dijkstra算法是个优秀的算法,但它不能运用到带有负权边的图中。 于是乎,Bellman-Ford算法登场了~ 先上一张带有负权边的图(n=5n=5n=5)作为例子,依旧是求顶点1到其他顶点的最短距离: 准备工作 我们用三个一维数组表示所有边,其中u[i],v[i],w[i]分别表示第i条边的起点、终点和权值,边给出的顺序如...

一个学习困难症患者的破博客 442

傅里叶变换实战:用Python手把手教你分析音频频谱(附完整代码)

本文详细介绍了如何使用Python实现傅里叶变换进行音频频谱分析,涵盖音频加载、预处理、FFT应用、频谱可视化及特征提取等关键步骤。通过实战案例和完整代码,帮助开发者掌握数字信号处理技术,特别适合音频分析和音乐信息检索领域的应用。

weixin_29090677的博客 150

模式分类识别 | TCN时间卷积神经网络多特征分类预测(Matlab完整程序)

模式分类识别 | TCN时间卷积神经网络多特征分类预测(Matlab完整程序)

前程算法屋的博客 748

SPFA(队列优化的Bellman-Ford算法)

SPFA(Shortest path faster algorithm) 算法思想基于Bellman-Ford算法 进行优化的方式是 在进行某一次松弛操作中 如果起点到一个点的距离不变 那么以这个点为中转点能到达的点距起点的距离不变 如果这个点的距离发生了变化 就将这个点入队列 以求通过这个点中转的点距起点的位置是否发生了变化 vis数组标记当前位于队列中的顶点 显然 一个顶点出队列时 要取消标记...

zzqwtc的博客 1787

ADS基础教程20 - 电磁仿真(EM)参数化仿真

一、引言二、参数化设置1.参数定义2.参数赋值3.创建EM模型和符号四、总结1)在Layout视图,菜单栏中选中EMComponent2)在弹出的参数编辑框中,采用标称/扰动()设计。使用子网(Subnetwork)参数。这些方法是互斥的,在为单个组件定义参数时不能将它们组合起来。标称/扰动(Nominal/Perturbed)参数使用平面化布局场景,并且只包含端口和原始图形形状(如多边形、矩形和圆形)时定义。

XZ_ZC的博客 4029

图论 21. Bellman_ford 队列优化算法(又名SPFA)(无负权回路情况)

大家可以发现 Bellman_ford 算法每次松弛 都是对所有边进行松弛。

m0_49844155的博客 858

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

【图论——第五讲】Bellman-Ford算法求单源最短路及其队列优化SPFA 算法

算法图论题中关于存在负边权的单源最短路Bellman-Ford算法以及其队列优化Spfa算法

m0_63233163的博客 762

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

POJ3259 bellman-ford算法及其队列优化——SPFA算法

POJ3259 bellman-ford算法及其队列优化——SPFA算法 题目分析 http://poj.org/problem?id=3259 标准的单源权值可负回路问题 bellman-ford #include<iostream> #include<vector> using namespace std; const int INF=0x3f3f3f3f; str...

qq_43513855的博客 197

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

【最短路算法】第三弹:一文学懂spfa 算法(队列优化的Bellman-Ford算法)

前面,我们分别介绍了Dijkstra算法(【最短路算法】一篇文章彻底弄懂Dijkstra算法|多图解+代码详解)和Bellman-Ford算法【最短路算法】第二弹:一文弄懂Bellman-Ford(贝尔曼福特算法)前者用于求单源、正权边最短路问题,后者用于求单源、带负权边最短路问题。通过对Bellman-Ford算法讲解,我们知道,Bellman-Ford算法美中不足的一点在于时间复杂度是O(nm),时间复杂度过高。今天,我们学习的spfa算法,优化了Bellman-Ford算法,

Yaoyao2024的博客 1169

DAY65||Bellman_ford 队列优化算法(又名SPFA)|bellman_ford之判断负权回路|bellman_ford之单源有限最短路

输出一个整数,表示从城市 src 到城市 dst 的最低运输成本,如果无法在给定经过城市数量限制下找到从 src 到 dst 的路径,则输出 "unreachable",表示不存在符合条件的运输方案。路径中存在负权回路,从 1 -> 2 -> 3 -> 1,总权值为 -1,理论上货物运输商可以在该回路无限循环赚取政府补贴,所以输出 "circle" 表示已经检测出了该种情况。共有 n 个编号为 1 到 n 的城市,通过道路网络连接,网络中的道路仅允许从某个城市单向通行到另一个城市,不能反向通行。

2301_79865280的博客 1190

代码随想录Day60:图论(Bellman_ford 队列优化算法SPFA、Bellman_ford 之判断负权回路、Bellman_ford 之单源有限最短路)

所有边进行的第二次松弛,minDist数组为 : -2 -2 -1 0 所有边进行的第三次松弛,minDist数组为 : -3 -3 -2 -1 所有边进行的第四次松弛,minDist数组为 : -4 -4 -3 -2 (本示例中k为3,所以松弛4次)最后计算的结果minDist[4] = -2,即 起点到 节点4,最多经过 3 个节点的最短距离是 -2,但 正确的结果应该是 1,即路径:节点1 -> 节点2 -> 节点3 -> 节点4。但是,真正有效的松弛,是基于已经计算过的节点在做的松弛。

m0_73724472的博客 1307

代码随想录Day60 Bellman_ford 队列优化算法(又名SPFA),bellman_ford之判断负权回路,bellman_ford之单源有限最短路。

代码随想录Day60 Bellman_ford 队列优化算法(又名SPFA),bellman_ford之判断负权回路,bellman_ford之单源有限最短路。

get_money_的博客 1067

day60 Bellman_ford 队列优化算法(又名SPFA)bellman_ford之判断负权回路

Bellman_ford 队列优化算法(又名SPFA)Bellman_ford 算法 每次都是对所有边进行松弛,其实是多做了一些无用功。。我们在加入队列的过程可以有一个优化,

2401_87983916的博客 1009

SPFA算法(Bellman-ford算法队列优化)(邻接表)(C++实现)

SPFA算法(Bellman-ford算法队列优化)(贝尔曼-福特算法队列优化)(邻接表)(C++实现) 实现代码 /* author : eclipse email : eclipsecs@qq.com time : Sat Apr 18 17:39:56 2020 */ #include<bits/stdc++.h> using namespace std; const ...

qq_44486439的博客 1011

图论day64 :最短路径算法 | SPFA(Bellman_ford的队列优化版)、城市间货物运输 I、Ⅱ、Ⅲ、Bellman_ford算法思维导图汇总

图论day64:最短路径 | SPFA(Bellman_ford的队列优化版)、94.城市间货物运输 I(卡码网)【SPFA算法 + 邻接表优化】、95.城市间货物运输 II(判断负权回路)、96.城市间货物运输 III【已知有负权回路,该如何计算】、Bellman_ford算法思维导图汇总

2402_84438596的博客 1282

代码随想录算法训练营第五十二天 | Bellman_ford 队列优化算法(又名SPFA)、Bellman_ford之判断负权回路、Bellman_ford之单源有限最短路

代码随想录算法训练营第五十二天 | Bellman_ford 队列优化算法(又名SPFA)、Bellman_ford之判断负权回路、Bellman_ford之单源有限最短路

dewi的博客 1033

SPFA算法(Bellman_ford 队列优化算法)

共有 n 个编号为 1 到 n 的城市,通过道路网络连接,网络中的道路仅允许从某个城市单向通行到另一个城市,不能反向通行。示例中最佳路径是从 1 -> 2 -> 5 -> 6,路上的权值分别为 1 2 -2,最终的最低运输成本为 1 + 2 + (-2) = 1。接下来为 m 行,每行包括三个整数,s、t 和 v,表示 s 号城市运输货物到达 t 号城市,道路权值为 v (单向图)。与Bellman的主要区别就是加入了一个队列,只有上次更新过的下次才需要更新,优化了很多不必要的判断,实现用的是邻接表。

m0_54283072的博客 1034

Bellman_ford 队列优化算法(又名SPFA)

【代码】Bellman_ford 队列优化算法(又名SPFA)

weixin_71888551的博客 384
上一篇: Java程序打包成exe可执行文件
下一篇: Poj 1973 Software Company(二分+并行DP)
TaiSung
博客等级 码龄15年 49粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值