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)\)

  • 步骤

    1. 使用 Bellman-Ford 算法 计算从 \(s\) 到所有原节点的最短路径,结果记为 \(h(v)\)。
    2. 若检测到负权环,算法终止(此时原图无有效最短路径)。

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)\) 有:

\[h(v) \leq h(u) + w(u, v)
\]

移项得:

\[w(u, v) + h(u) - h(v) \geq 0
\]

因此,调整后的权重 \(w'(u, v)\) 非负,Dijkstra算法可正确运行。

2 最短路径的等价性

设原图中一条路径 \(p = v₀ → v₁ → ... → vₖ\) 的权重和为:

\[W(p) = \sum_{i=0}^{k-1} w(v_i, v_{i+1})
\]

调整后的权重和为:

\[W'(p) = \sum_{i=0}^{k-1} [w(v_i, v_{i+1}) + h(v_i) - h(v_{i+1})] = W(p) + h(v₀) - h(v_k)
\]

路径上的 \(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 全源负权最短路径算法详解的更多相关文章

  1. sip鉴权认证算法详解及python加密

    1. 认证和加密    认证(Authorization)的作用在于表明自己是谁,即向别人证明自己是谁.而相关的概念是MD5,用于认证安全.注意MD5仅仅是个hash函数而已,并不是用于加密.因为ha ...

  2. Johnson 全源最短路径算法

    解决单源最短路径问题(Single Source Shortest Paths Problem)的算法包括: Dijkstra 单源最短路径算法:时间复杂度为 O(E + VlogV),要求权值非负: ...

  3. Johnson 全源最短路径算法学习笔记

    Johnson 全源最短路径算法学习笔记 如果你希望得到带互动的极简文字体验,请点这里 我们来学习johnson Johnson 算法是一种在边加权有向图中找到所有顶点对之间最短路径的方法.它允许一些 ...

  4. 【最短路径Floyd算法详解推导过程】看完这篇,你还能不懂Floyd算法?还不会?

    简介 Floyd-Warshall算法(Floyd-Warshall algorithm),是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似.该算法名称以 ...

  5. 【学习笔记】 Johnson 全源最短路

    前置扯淡 一年多前学的最短路,当时就会了几个名词的拼写,啥也没想过 几个月之前,听说了"全源最短路"这个东西,当时也没说学一下,现在补一下(感觉实在是没啥用) 介绍 由于\(spf ...

  6. Johnson全源最短路

    例题:P5905 [模板]Johnson 全源最短路 首先考虑求全源最短路的几种方法: Floyd:时间复杂度\(O(n^3)\),可以处理负权边,但不能处理负环,而且速度很慢. Bellman-Fo ...

  7. Johnson 全源最短路

    学这个是为了支持在带负权值的图上跑 Dijkstra. 为了这个我们要考虑把负的权值搞正. 那么先把我们先人已经得到的结论摆出来.我们考虑先用 SPFA 对着一个满足三角形不等式的图跑一次最短路,具体 ...

  8. “全栈2019”Java多线程第八章:放弃执行权yield()方法详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  9. 第三十节,目标检测算法之Fast R-CNN算法详解

    Girshick, Ross. “Fast r-cnn.” Proceedings of the IEEE International Conference on Computer Vision. 2 ...

  10. 第三十一节,目标检测算法之 Faster R-CNN算法详解

    Ren, Shaoqing, et al. “Faster R-CNN: Towards real-time object detection with region proposal network ...

随机推荐

  1. ELASTICSEARCH 读写性能优化

    ELASTIC 写i性能优化 refresh translog flush refresh 优化 translog优化 flush 优化 读性能优化 shard 设置

  2. jsp移动端和pc端页面判断及切换

    function goPAGE() { if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobi ...

  3. 从底层源码深入分析Bean的实例化

    生命周期的整体流程 Spring 容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁. ...

  4. IOS打开对应后缀文件

    IOS打开对应后缀文件 通过ShareExtension打开 点击文件共享后出现的上方列表,如下图 在 info.plist 中添加 Document types <key>CFBundl ...

  5. 源启行业AI平台 银行智能业务的驱动引擎

    AI技术已经深入金融行业,在营销.渠道.风控等领域广泛应用,但人工智能开发与应用面临成本高.难度大.门槛高.重复建设.无统一管理复用AI模型资产等问题,这些问题也正是源启AI行业平台要解决的. 源启行 ...

  6. 走向更强的 Literal 的时代

    正如 声明式编程的没落 - Inshua - 博客园 分析,声明式编程由于不符合软件工程需要,实际上正在淘汰,但与此同时,它的特征被过程式编程吸收为了Literal,中文翻译字面量. 什么是 Lite ...

  7. 【Python】【Pandas】使用concat添加行

    添加行 t = pd.DataFrame(columns=["姓名","平均分"]) t = t.append({"姓名":"小红 ...

  8. Linux安装EasyConnect

    首先下载并安装EasyConnect客户端 wget http://download.sangfor.com.cn/download/product/sslvpn/pkg/linux_767/Easy ...

  9. Ubuntu 22.04 LTS 代号已经公布:那就是 Jammy Jellyfish

    Ubuntu 22.04 LTS 代号已在 Ubuntu 开发之家 Launchpad 上公布. 在字母系列中的字母"I"之后,是"J". 因此,Canonic ...

  10. Docker学习笔记(一) - Docker安装

    1.安装yum-utils yum install yum-utils device-mapper-persistent-data lvm2 复制 安装yum-utils是为方便添加yum源使用的,d ...