单源最短路径SSSP之Bellman-Ford算法

最短路径 最短路径算法 单源最短路径算法简称SSSP,是说给定一张有向图,从1号顶点出发,求出长度为n的d数组,其中d数组表示从1到i的最短路径的长度 对于无向图,我们通常把无向边看成两条相反的有向边,也就是在存储的时候存两次 单源,就是说以一个固定的点为起点的最短路径 dijkstra算法 O(N2) dijkstra算法的流程如下: 1.初始化最短路径数组d[1]=0表示自己到自己的长度为0,其他的点设置为正无穷 2.找出来一个没有被标记的、d[x]最小的节点x,然后标记x 3.扫描x的所有链边(x,y,z)如果 阅读详情

Bellman-Ford算法和Dijkstra算法都是求解图的最短路径的算法。Bellman是求单源点到各个顶点的最短路径,适用条件为有向或无向图,权重可为负值。当存在负权环路时,算法返回一个false值。该算法效率比较低,需要对边进行 |V|- 1 次松弛操作

Bellman-Ford算法寻找单源最短路径的时间复杂度为O(V*E)。(V为给定图的顶点集合,E为给定图的边集合)

两者区别在于:Dijkstra要求图中不存在边权值之和为负数的环路,否则算法无法收敛;Bellman-Ford算法可以检测出图中是否存在权值之和为负数的环路。

 

Bellman-Ford算法功能:

给定一个加权连通图,选取一个顶点,称为起点,求取起点到其它所有顶点之间的最短距离,其显著特点是可以求取含负权边 图的单源最短路径。

 

Bellman-Ford算法思想:

  • 1. 初始化所有点:每个点保存一个dist值,表示从源点到达这个点的最短距离,将原点的值设为0,其它的点的值设为无穷大 +∞(表示不可达),即: dist[v] ← +∞, dist[s] ←0 。
  • 2. 迭代求解:进行循环,循环下标为从1到 n-1(n为图中节点的个数)。在循环内部,遍历所有的边,对边集E中的每条边进行松弛操作。使得顶点集V中的每个顶点v的最短距离估计值逐步逼近其最短距离;(运行 |v|-1 次) 。

(松弛操作只需要进行 n-1 次。因为在一个含有n个顶点的图中,任意两点之间的最短路径最多包含n-1条边。

其实,n-1 次 只是一个上界(最大值),很多时候我们会在n-1轮之前就求出了最短路径。)

  • 3. 检验负权回路:遍历途中所有的边(edge(u,v)),判断边集E中的每一条边的两个端点是否收敛。因为第2步中已经完成了 |v|-1 次 松弛操作,在第3步中,如果存在d(v)> d (u) + w(u,v),则返回false,说明存在未收敛的顶点,也就是存在从源点可达的负权回路,这种情况下算法无解。否则返回true,算法可以运行处结果,并且从源点可达的顶点 v 的最短距离保存在 dist[v] 中。

(如果经过n-1次松弛操作后,仍然可以继续成功松弛,那么,此图必定存在负权回路。)

 

来看一个例子理解一下:

如下图所示,按 Bellman–Ford 算法思路 获取 起点A 到各节点的最短路径。由于该图顶点总数 n=5 个顶点,所以需要进行 5-1 = 4 次的遍历更新操作(即松弛操作),在每次松弛操作过程中,若能发现更短的路径则更新对应节点的 dist值。

1.首先初始化各节点,列出起点A到各个节点耗费的时间:

父节点节点初始化dist执行线路
AA0-
-B∞-
-C

∞

-
-D∞-
-E∞-

 

 

 

 

 

 

 

2.进行第一次对所有边的松弛操作:

2.1 统计经过1条边所能到达的节点的值AB,AC:

AB:-1 AC:4

父节点节点

dist

执行线路
AA0-
AB-1A->B
AC

4

A->C
-D∞ 
-E∞ 

 

 

 

 

 

 

 

2.2 统计经过2条边所能到达的节点的值BC,BD,BE:

BC:3 BE:2 BD:2

其中:以节点C为例,因为满足: dist(C) > dist(B) + weight(BC) ,即 4 > -1 + 3 ,所以C的dist更新为2

父节点节点dist执行线路
AA0-
AB-1A->B
BC

2

A->B->C
BD1A->B->D
BE1A->B->E

 

 

 

 

 

 

 

2.3 统计经过3条边所能到达的节点的值ED,DC:

ED:-3 DC:5 DB:1

父节点节点dist执行线路
AA0-
AB-1A->B
BC

2

A->B->C
ED-2A->B->E->D
BE1A->B->E

 

 

 

 

 

 

 

3. 尝试再进行第2次遍历,对所有边进行松弛操作,发现没有节点需要进行更新,此时便可以提前结束遍历,优化效率

即:2.3中的表格就是最终结果,求出了源点A 到各个节点的最短路径与线路。

 

算法伪代码:

 

算法的核心代码:

//【核心代码】
for(int k=1; k<=n-1; k++)
{
    for(int i=1; i<=m; i++)
    {
        // 松弛操作
        // 这里也可以写为 dist[v[i]]=min(dist[v[i]],dist[u[i]]+w[i])
        if(dist[v[i]] > dist[u[i]] + w[i]) 
        {
            dist[v[i]] = dist[u[i]] + w[i];
        }
    }
}

 

那么算法步骤第三步为何要判断是否存在负环路呢?存在负环路的情况为何无解呢?

对刚刚例子中的图进行修改 将B->D 的2 改为 -2,这就使得B<->D这形成了负环路,所谓的负环路指的是环路权重之和为负数,比如下图中 1 + (-2) = -1 < 0即为负环路。

因为负环路可以无限执行循环步骤,试想,可以在 B->D->B->D...这边无限循环,所以B、D的取值可以无限小, 然后当B、D取值无限小后再从B、D节点出发到达其他各个节点,都会导致其它节点的取值同样接近无限小。所以,对于负环路的情况,Bellman–Ford 只能判断出图存在负环路,返回False,无法求出各个节点最短路径的意义。

以上的例子部分来自作者:CodeInfo 链接:https://juejin.im/post/5b77fec1e51d4538cf53be68
 

Java代码:

import java.util.Scanner;

public class BellmanFord {
    
    public long[] dist;       //dist数组 用于存放第0个顶点到其它顶点之间的最短距离
    
    //-------内部类,表示图的一条加权边
    class edge {
        public int begin;   //边的起点
        public int end;     //边的终点
        public int weight;  //边的权值
        
        edge(int begin, int b, int value) {  //带参构造
            this.begin = begin;
            this.end = end;
            this.weight = weight;
        }
    }
    //-------内部类结束
    
    
    //返回第0个顶点到其它所有顶点之间的最短距离
    public boolean getShortestPaths(int n, edge[] A) {  //n是顶点总数, A是边集
    	dist = new long[n];
    	//第一步
        for(int i = 1; i < n; i++)  //i从1开始而不是从0开始,是因为源点不用初始化为无穷大
        	//初始化第0个顶点到其它顶点之间的距离为无穷大,即dist[i],此处用Integer型最大值表示
        	dist[i] = Integer.MAX_VALUE;  
        
        //第二步
        for(int i = 1; i < n; i++) {
            for(int j = 0; j < A.length; j++) {
            	//松弛操作
            	//意味着最短路径是先从s到a,再由a->b, 所以更新dist[b]的数据
                if(dist[A[j].end] > dist[A[j].begin] + A[j].weight)   
                	dist[A[j].end] = dist[A[j].begin] + A[j].weight;
            }
        }
        
        //第三步
        boolean judge = true;  //judge为判断是否有负权环路的标志,默认不含有
        for(int i = 1; i < n; i++) {   //判断给定图中是否存在负环
            if(dist[A[i].end] > dist[A[i].begin] + A[i].weight) {  //如果仍然可以继续成功松弛
                judge = false;  //则存在负权环路,算法无法进行下去
                break;
            }
        }
        return judge;
    }
    
    public static void main(String[] args) {
        BellmanFord test = new BellmanFord();
        Scanner in = new Scanner(System.in);
        System.out.println("请输入一个图的顶点总数n和边总数p:");
        int n = in.nextInt();
        int p = in.nextInt();
        edge[] A = new edge[p];
        System.out.println("请输入具体边的数据:");
        for(int i = 0; i < p; i++) {
            int a = in.nextInt();
            int b = in.nextInt();
            int w = in.nextInt();
            A[i] = test.new edge(a, b, w);
        }
        if(test.getShortestPaths(n, A)) {
            for(int i = 0; i < test.dist.length; i++)
                System.out.print(test.dist[i]+" ");
        } else
            System.out.println("给定图中存在负环,没有最短距离");
    }

}

结果:

 

另一种图解:(摘自啊哈算法)

到达第4轮时,我们发现,其实第4轮的操作是多余的,因为dis数组的值没有发生任何变化。

STOC 2025 | 清华团队颠覆性突破:无需排序的SSSP算法,40年Dijkstra统治时代终结 清华大学团队在STOC 2025上提出了一种颠覆性的单源最短路径算法,首次在理论上突破了Dijkstra算法保持了近40年的时间复杂度壁垒。该算法绕过了关键的“排序障碍”,实现了O(m log^{2/3} n)的时间复杂度,为处理海量图数据提供了全新的理论范式和潜在的效率飞跃。 阅读详情

相关推荐

STOC 2025 | 清华团队突破单源最短路径算法极限,Dijkstra 40年统治地位终结

清华大学团队在STOC 2025上提出全新确定性算法,将单源最短路径问题的时间复杂度降至O(m log²/³ n),首次在理论上突破了Dijkstra算法在稀疏图上长达40余年的O(m + n log n)时间界限。该成果成功绕过了“排序障碍”,融合了Dijkstra与Bellman-Ford算法的思想,为图算法基础理论开辟了新方向,并对处理海量图数据的实际应用具有重要启示意义。

weixin_29291573的博客 93

图算法(八):单源最短路算法(SSSP)【适用场景:用于网络路由、路径设计等场景】【给出从给定的一个节点(称为源节点)出发到其余各节点的最短路径长度】

一、概述 单源最短路算法(SSSP)计算了图论中的一个经典问题,给出从给定的一个节点(称为源节点)出发到其余各节点的最短路径长度。 适用场景:单源最短路算法(SSSP)适用于网络路由、路径设计等场景。 二、 三、 参考资料: 单源最短路算法(SSSP) ...

u013250861的博客 1401

探索单源最短路径与所有对最短路径算法

本文深入探讨了单源最短路径(SSSP)和所有对最短路径(APSP)问题的解决方案,介绍了Dijkstra和Bellman-Ford算法以及Floyd-Warshall算法。通过分析各种算法的时间复杂度和适用场景,文章强调了在编程竞赛中选择合适算法的重要性,并通过示例和练习题巩固了理论知识。

weixin_33814090的博客 539

【大数据】SSSP算法

SSSP算法,即单源最短路径算法(Single-Source Shortest Path),用于在加权图中找到从单一源点到所有其他顶点的最短路径。该算法的核心目标是确定每个顶点到源点的最短路径长度,并可能同时构建出这些路径。

大雨淅淅的博客 2221

KingbaseAnalyticsDB 学习之madlib图计算能力

vertex_id:TEXT类型,缺省值为‘id’,vertex_table表中包含顶点的列名。边表必须包含源顶点、目标顶点和边长三列。weight:从源顶点到目标顶点最短路径的边长合计,使用weight入参的值作为列名。vertex_table:TEXT类型,包含图中顶点数据的表名。dest (INTEGER):边表中包含目标顶点的列名,缺省值为‘dest’。vertex_id:目标顶点ID,使用vertex_id入参的值作为列名。parent:在最短路径上,本顶点的上一节点,列名为‘parent’。

liuzhiliang2010的博客 197

AI驱动的iOS逆向工程自动化:14阶段工作流与Ghidra集成实践

逆向工程是软件安全分析的核心技术,通过反汇编、调试等手段解析程序内部逻辑与数据流。其原理在于将编译后的二进制代码还原为可理解的逻辑结构,从而发现潜在漏洞或理解软件行为。在移动安全领域,iOS逆向工程具有重要技术价值,能够用于安全审计、漏洞挖掘与恶意软件分析。传统iOS逆向依赖ipsw、class-dump、Frida等工具链组合,存在学习曲线陡峭与流程碎片化问题。本文介绍的ios-reverse-skills项目创新性地将14阶段逆向工程方法论封装为AI可调用的标准化脚本集,通过Ghidra脚本实现Swif

weixin_27268733的博客 434

SSSP:Single Source Shortest Path

SSSP:Single Source Shortest Path Maiter 4.2.1 SSSP算法广泛应用于社交网路和网页地图。给定一个点sss,SSSP算法算出在有向有权图中s节点到其余节点的最短距离。初始时,除节点sss到源节点的距离ds0d_{s}^0ds0​初始化为000外,其余每个节点jjj到sss的距离dj0d_{j}^0dj0​初始化为∞\infty∞。在每次迭代时,sss到jjj的距离djd_{j}dj​根据下列公式进行更新: djk=min{d1k−1+A(1,j),d2k−1+A(

weixin_41579721的博客 1015

DSSAD自动驾驶行车记录系统体系结构和应用

通过对其感知、决策、控制等模块的详细研究,以及对商业化和消费市场发展趋势的分析,为该领域的研究和实践提供有价值的参考。通过克服技术、安全与隐私、法规与政策等方面的挑战,并紧跟人工智能、云端服务、用户体验等发展趋势,DSSAD系统将更好地适应自动驾驶行业的发展,提供更安全、智能、便捷的驾驶辅助服务。DSSAD体系结构通过数据收集模块、加密链接和数据存储模块和数据读取模块等关键模块的协同作用,构建了一个强大而灵活的自动驾驶数据记录系统,为未来智能出行提供了坚实的技术基础。

一只老虎的专栏 2208

【最短路算法】第二弹:一文弄懂Bellman-Ford(贝尔曼福特算法)

【最短路算法】一篇文章彻底弄懂Dijkstra算法|多图解+代码详解Dijstra算法用于计算单源正权边的最短路问题今天学习的贝尔曼福特算法,是用于计算单源,且可含负权边的最短路问题用于求解单源、有负权边的最短路问题实现通过m次迭代求出从起点到终点不超过m条边构成的最短路径其优于Dijkstra的方面是边的权值可以为负数、实现简单,缺点是时间复杂度过高。

Yaoyao2024的博客 2万+

FPGA人脸识别检测(先获取人脸图像以及灰度二值化)

由于图片有空洞等缺陷,所以后面要进行中值滤波、腐蚀、膨胀等算法处理,然后再对人脸进行框选,最后显示出来。最终的成像应该是下面这样的。(后面有时间再接着做哈哈哈)5、通过modelsim将操作后的图片数据写入gray_img.txt里面后,用matlab将txt转成图片。1、先用matlab将图片转换成txt数据,代码如下。读取图片的方式按照博客咸鱼里的方式来做,如下。2、FPGA读取txt数据。4、FPGA顶层模块及仿真。3、FPGA灰度二值化。

weixin_46312715的博客 2531

DAC8568 Controller

DAC8568 ControllerDAC8568 简介串行接口三级目录 DAC8568 简介 PIN Description Name Description LDAC‾\overline{LDAC}LDAC load DACs SYNC‾\overline{SYNC}SYNC 低电平有效,电平触发控制, 该输入为输入数据的帧同步信号. 当SYNC为低,使能DAC内输入移位寄存器,并在随后的所有时钟沿采样数据。 在第32个时钟之后,DAC更新输出。 若不到32个时钟SYNC被置高(即

u010170039的博客 5130

【最短路算法】Dijkstra+heap和SPFA的区别

单源最短路问题(SSSP)常用的算法有Dijkstra,Bellman-Ford,这两个算法进行优化,就有了Dijkstra+heap、SPFA(Shortest Path Faster Algorithm)算法。这两个算法写起来非常相似。下面就从他们的算法思路、写法和适用场景上进行对比分析。如果对最短路算法不太了解,可先看一下相关ppt:最短路 为了解释得简单点,以及让对比更加明显,我...

dingguayi7025的博客 364

LoFTR训练避坑指南:从零到一复现论文训练流程

本文是一份详细的LoFTR模型训练避坑指南,旨在帮助开发者从零开始复现论文训练流程。文章系统性地讲解了环境配置、数据准备、代码调试与显存优化等关键步骤,并针对常见的训练错误提供了解决方案,确保训练过程顺利进行。

weixin_29091837的博客 204

WHUST 2017 Div.2 Day 15 [2017-08-06](图论八题)

A - Silver Cow Party POJ - 3268 题目大意 做法 到汇点T 连容量为a和b的两条边,求最大流即可 复杂度 O(1) (写一下题目的坑点,如“此题十分变态,倍增的SA不能过,得用DC3或者SAM”,考虑到能力上的差别,慎用小众的缩写(自己衡量)) AC-Code (C++) (可以附上AC代码,也可以附上Gi

zhuangzi926的博客 303

奥比中光Dabai深度相机SDK在Ubuntu22.04的兼容性安装指南

本文详细指导如何在Ubuntu22.04系统上安装奥比中光Dabai深度相机的SDK。针对新旧版本不兼容的核心问题,重点推荐使用经过验证的v1.10.18版本SDK,并提供了从系统依赖检查、SDK下载安装、Python环境配置到编译测试的完整步骤,帮助用户成功解决安装难题并实现相机驱动。

j2k3l4的博客 1000

Codex入门19-数据库操作(解放双手:用自然语言写SQL、建表和数据迁移)

写 SQL 是后端开发的日常,但复杂的 JOIN、子查询、窗口函数总让人头疼。本文教你用 Codex CLI 实现:自然语言直接生成 CREATE TABLE、复杂 SQL 查询、数据库迁移脚本(Prisma/Knex/Alembic)、ORM 模型代码(SQLAlchemy/TypeORM)、甚至自动生成数据库文档。重点强调安全红线——永远不要让 AI 直接连接生产数据库。从需求描述到完整数据库层代码,一篇搞定。

yueyeguzhuo的专栏 234

INF421 - Amphi 6: Graph [最短路径:Dijkstra,Bellman-Ford,Floyd]

INF421 - Amphi 6: Graph1. Shortest Path Problem1.0 基本概念1.1 Shortest Paths Problems:SSSP: Single-Source shortest pathASPS: All-Pair Shortest Paths1.2 ???? Exchange Property2. Dijkastra Algorithm2.0 问题描述: Connected Graph, Non-Negative Edge Weights SSSP2.1 Ke

weixin_44495738的博客 708

华为OD机试双机位C卷-统计差异值大于相似值二元组个数(C/C++/Py/Java/Js/Go)

华为OD机试(机考)双机位C卷 【统计差异值大于相似值二元组个数】,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试 - 统计差异值大于相似值二元组个数

qq_45776114的博客 783

清华突破计算机科学60年瓶颈,最短路径算法分析 小白入手 (二)

本文系统比较了常见最短路径算法的性能特点:Dijkstra适用于非负权图(O((V+E)logV)),Bellman-Ford能处理负权边并检测负环(O(VE)),Floyd-Warshall适合小规模全点对问题(O(V³)),A*算法可利用启发式信息。针对不同场景提出选择策略,并介绍了双向搜索、分层技术等优化方法。文章还分析了交通导航、网络路由等实际应用案例,并指出动态图处理、量子计算应用等未来研究方向。最后强调应根据具体问题特点选择合适算法或组合多种算法,该领域仍具较大研究潜力。

华为开发者布道师,天府英才计划,致力于大数据+AI 的应用创新,助力企业与个人AI创新赋能。 1105

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

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

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

吴文虎图论学习日志——第二章

最短路径的算法及其应用:   算法有很多,包括上面没有讲到的和讲到的: SSSP(单源最短路径):1.标号法    2.Dijkstra(可以用heap优化)  3.Bellman_ford(可以检测负环)     4.SPFA(可以检测负环,还可以继续优化,不过还没学) 所有点对的最短路径:1.可以求N次SSSP    2.Floyd算法   该章提到的应用问题:   1. 求图

Airarts_的专栏 4793

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

单源最短路径SSSP之松弛操作

单源最短路径SSSP算法中使用了 松弛(relaxation)操作,即更新两点的最短路径 形象的理解: 原来用一根橡皮筋连接a、b两点,现在有一点v到b的距离更短,则用v点替换橡皮筋的a点,使得v、b连接在一起。这样缓解橡皮筋紧绷的压力,使其变得松弛,即松弛操作。 我们规定每个节点都有一个 dist 值,dist[v] 值记录的是从源点可达的顶点v的最短距离,每个节点也都有一个p指针指向...

SpringRolls的博客 1406

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

清华团队新算法如何超越Dijkstra?手把手解析单源最短路径的40年突破

本文解析了清华团队如何突破单源最短路径(SSSP)40年瓶颈,提出超越Dijkstra算法的新方法。通过递归分区与前沿缩减技术,新算法在时间复杂度上实现O(m log²ᐟ³n)的突破,特别适用于大规模有向图。文章详细对比了新旧算法的优劣,并探讨了该创新思维在图论及其他领域的应用潜力。

weixin_30772105的博客 388

图论$\cdot$最短路问题

Dijkstra单源最短路径算法 Dijkstra可以计算出发点到每个点的最短路,及单源最短路径(SSSP)。这一特点使得Dijkstra常常用来进行其他算法的预处理。用Dijkstra算法计算最短路的代码如下: 注:代码注释参见《算法竞赛入门经典——训练指南》(刘汝佳) 1 struct Dijkstra{ 2 int n, m; 3 vector&l...

weixin_33713503的博客 773

Bellman-Ford 单源最短路径算法

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

weixin_30236595的博客 148
上一篇: Dijkstra算法解析及Java代码实现(附图)
下一篇: 连接数据库错误 Network error IOException:Connection refused:connect 解决办法
SpringRolls
博客等级 码龄9年 73粉丝 129原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值