Johnson 全源负权最短路径算法详解
Floyd-Warshall算法可以求解出图内任意两点的最短路径,适用于稠密图,但时间复杂度为 \(O(n³)\);Dijkstra算法求解单源最短路径的时间复杂度为 \(O(m + n log n)\),对每个节点都做一次,也可以达成全源最短路径,但是这个方法仅适用于非负权边图。
Johnson 算法被设计来解决此问题,其支持负权边(当然不能有负权环)。综合两个算法的优势,时间复杂度 \(O(nm + n² log n)\),在稀疏图中显著优于 Floyd-Warshall,结合了 Dijkstra 的高效性与 Bellman-Ford 的灵活性。
1 添加虚拟节点
- 操作:在原始图 \(G\) 中添加一个虚拟节点 \(s\),并添加从 \(s\) 到所有原节点的边,权重为0。
- 目的:为后续计算势能函数做准备。
2 计算势能函数 \(h(v)\)
- 步骤:
- 使用 Bellman-Ford 算法 计算从 \(s\) 到所有原节点的最短路径,结果记为 \(h(v)\)。
- 若检测到负权环,算法终止(此时原图无有效最短路径)。
3 调整边权为非负值
- 公式:对原图中每条边 \((u, v)\),调整权重为:
\[w'(u, v) = w(u, v) + h(u) - h(v)
\] - 关键性质:经过这样调整,调整后所有新的边权重 \(w'(u, v)\) 均为非负。且满足“原图的最短路同样是新图的最短路”
4 运行Dijkstra算法
- 操作:对调整后的图,为每个节点 \(u\) 运行一次Dijkstra算法,得到最短路径 \(d'(u, v)\)。
5 还原原始最短路径
- 公式:原始图中 \(u\) 到 \(v\) 的最短路径为:
\[d(u, v) = d'(u, v) - h(u) + h(v)
\]
为什么是对的?
1 边权调整的非负性
\(h\) 是虚拟点到节点的距离,根据 Bellman-Ford 的最短路径性质,对任意边 \((u, v)\) 有:
\]
移项得:
\]
因此,调整后的权重 \(w'(u, v)\) 非负,Dijkstra算法可正确运行。
2 最短路径的等价性
设原图中一条路径 \(p = v₀ → v₁ → ... → vₖ\) 的权重和为:
\]
调整后的权重和为:
\]
路径上的 \(h\) 被抵消,由于 \(h(v₀) - h(v_k)\) 是常数,原图与新图上任意对应两个点之间的所有路径都只相差常数,那么原图最短路径仍然是新图最短路径。
时间复杂度分析
| 步骤 | 时间复杂度 |
|---|---|
| Bellman-Ford | \(O(nm)\) |
| n 次 Dijkstra | \(O(n(m + n log n))\) |
| 总时间 | $O(nm + n² log n) $ |
- 适用场景:稀疏图时,时间接近 \(O(n² log n)\),远优于Floyd-Warshall的 \(O(n³)\)。稠密图上差距缩小。
Johnson 全源负权最短路径算法详解的更多相关文章
- sip鉴权认证算法详解及python加密
1. 认证和加密 认证(Authorization)的作用在于表明自己是谁,即向别人证明自己是谁.而相关的概念是MD5,用于认证安全.注意MD5仅仅是个hash函数而已,并不是用于加密.因为ha ...
- Johnson 全源最短路径算法
解决单源最短路径问题(Single Source Shortest Paths Problem)的算法包括: Dijkstra 单源最短路径算法:时间复杂度为 O(E + VlogV),要求权值非负: ...
- Johnson 全源最短路径算法学习笔记
Johnson 全源最短路径算法学习笔记 如果你希望得到带互动的极简文字体验,请点这里 我们来学习johnson Johnson 算法是一种在边加权有向图中找到所有顶点对之间最短路径的方法.它允许一些 ...
- 【最短路径Floyd算法详解推导过程】看完这篇,你还能不懂Floyd算法?还不会?
简介 Floyd-Warshall算法(Floyd-Warshall algorithm),是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似.该算法名称以 ...
- 【学习笔记】 Johnson 全源最短路
前置扯淡 一年多前学的最短路,当时就会了几个名词的拼写,啥也没想过 几个月之前,听说了"全源最短路"这个东西,当时也没说学一下,现在补一下(感觉实在是没啥用) 介绍 由于\(spf ...
- Johnson全源最短路
例题:P5905 [模板]Johnson 全源最短路 首先考虑求全源最短路的几种方法: Floyd:时间复杂度\(O(n^3)\),可以处理负权边,但不能处理负环,而且速度很慢. Bellman-Fo ...
- Johnson 全源最短路
学这个是为了支持在带负权值的图上跑 Dijkstra. 为了这个我们要考虑把负的权值搞正. 那么先把我们先人已经得到的结论摆出来.我们考虑先用 SPFA 对着一个满足三角形不等式的图跑一次最短路,具体 ...
- “全栈2019”Java多线程第八章:放弃执行权yield()方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- 第三十节,目标检测算法之Fast R-CNN算法详解
Girshick, Ross. “Fast r-cnn.” Proceedings of the IEEE International Conference on Computer Vision. 2 ...
- 第三十一节,目标检测算法之 Faster R-CNN算法详解
Ren, Shaoqing, et al. “Faster R-CNN: Towards real-time object detection with region proposal network ...
随机推荐
- 打包jar 程序,同时将依赖报一起打包
1.概述 有些时候,我们打包一个java 程序,我需要将所有的依赖也一起打包,这样执行起来方便. 2.我们可以使用maven 插件实现 <build> <plugins> &l ...
- 强网杯2023 谍影重重3.0 wp
参考文章:[使用主动探测方法识别 U2hhZG93c29ja3M=(base64) 服务 - Phuker's Blog]:https://phuker.github.io/posts/U2hhZG9 ...
- 关于com组件的方法,以AE的IFieldsEdit为例
今天,有小伙伴问我,为什么在调用IFieldsEdit接口时,VS无法自动显示出AddFiled方法,而这个方法是确实存在的 在此,做下解答,因为这个方法被隐藏了.TypeLibFunc属性,被用来指 ...
- git 忽略某些文件
如果git项目里没有 '.gitignore' 文件,则需要执行下面的操作,生成一个 生成 '.gitignore' 文件 1. git bash 打开git窗口 执行:touch .gitign ...
- 履机乘变,轻舟便楫:源启分布式PaaS深度赋能企业级技术平台建设
导语 源启分布式PaaS平台围绕应用视角为用户提供应用运行的全生命周期管控能力,提供注册中心.服务路由.网关.服务治理等中间件技术支持,实现应用之间的联通,解决客户多厂商产品不兼容.产品组合不可选择. ...
- Windows 11 下 Virtualbox 6.1.34 出现 End kernel panic - not syncing: attempted to kill the idle task
前言小半年没用 Virtualbox 了,切换到了 VMware,今天又切换回去(无聊),但是安装虚拟机出现这个错误. 解决方法根据 Virtualbox 论坛的讨论[1]和[2],首先明确 系统必须 ...
- Qt开发经验小技巧261-265
代码中判断当前Qt库是32位还是64位,用QSysInfo::WordSize=32/64. QTreeView控件设置左侧branch图标大小,无法通过qss设置,万能大法查看源码得知控制宽度最后取 ...
- Qt开源作品16-通用无边框拖动拉伸
一.前言 相信各位CS结构开发的程序员,多多少少都遇到过需要美化界面的事情,一般都不会采用系统的标题栏,这样就需要无边框标题栏窗体,默认的话无边框的标题栏都不支持拉伸和拖动的,毕竟去掉了标题栏则意味着 ...
- Python设计模式(第2版)中文的pdf电子书
Python设计模式(第2版)中文的pdf电子书下载地址:百度云盘,提取码:dmem
- manim边做边学--动画轨迹
本篇介绍Manim中两个和动画轨迹相关的类,AnimatedBoundary和TracedPath. AnimatedBoundary聚焦于图形边界的动态呈现,能精准控制边界绘制的每一帧,助力我们清晰 ...