相关笔记

概览

本节介绍 Johnson算法,用于解决所有结点对的最短路径问题。该算法由 Donald B. Johnson 于1977年提出,巧妙地结合了22.1 Bellman-Ford算法22.3 Dijkstra算法的优势:先用 Bellman-Ford 通过重赋权(reweighting)技术将含负权边的图转化为所有边权非负的等价图,再对每个顶点运行 Dijkstra 算法。

要点列表:

  • Johnson算法的核心思想是重赋权:通过修改边权使得所有边权非负,同时保持最短路径不变
  • 重赋权需要添加一个超级源点,运行 Bellman-Ford 计算每个顶点的势函数
  • 新边权定义为 ,由三角不等式保证非负
  • 对重赋权后的图运行 次 Dijkstra,总复杂度为 ====
  • 对稀疏图(),Johnson算法优于23.2 Floyd-Warshall算法
  • 若 Bellman-Ford 检测到负权环,则报告图中不存在有效的最短路径

知识结构总览

flowchart TD
    A["23.3 稀疏图的Johnson算法"] --> B["动机: 稀疏图上的高效全源最短路"]
    A --> C["核心: 重赋权技术"]
    A --> D["算法流程"]
    A --> E["正确性证明"]
    A --> F["复杂度分析"]
    A --> G["与其他算法的对比"]

    B --> B1["Floyd-Warshall: O(V³) 对稀疏图不优"]
    B --> B2["V次Dijkstra: O(V(E+V lg V)) 在稀疏图上更优"]
    B --> B3["问题: Dijkstra不能处理负权边"]

    C --> C1["添加超级源点 s"]
    C --> C2["Bellman-Ford 计算 h(v) = δ(s,v)"]
    C --> C3["新边权 w'(u,v) = w(u,v) + h(u) - h(v)"]

    D --> D1["阶段1: 构造 G' 并运行 Bellman-Ford"]
    D --> D2["阶段2: 重赋权所有边"]
    D --> D3["阶段3: 对每个顶点运行 Dijkstra"]
    D --> D4["阶段4: 恢复原始距离 d[u][v] = d'[u][v]+h[v]-h[u]"]

    E --> E1["引理23.1: w'非负"]
    E --> E2["引理23.2: w'保持最短路径"]
    E --> E3["定理23.3: Johnson算法正确性"]

    F --> F1["Bellman-Ford: O(VE)"]
    F --> F2["V次Dijkstra: O(V(E+V lg V))"]
    F --> F3["总计: O(V² lg V + VE)"]

    G --> G1["稀疏图: Johnson < Floyd-Warshall"]
    G --> G2["稠密图: Johnson ≈ Floyd-Warshall"]

核心思想

2.1 动机:为什么需要Johnson算法

解决所有结点对的最短路径问题,前面已经介绍了两种方法:

如果图是稀疏图,即边数远小于顶点数的平方),我们自然想到:能否对每个顶点运行22.3 Dijkstra算法?Dijkstra的单次运行时间为 (使用二叉堆),运行 次的总时间为

时,,远优于 Floyd-Warshall 的

问题在于:Dijkstra算法要求所有边权非负。 如果原图中存在负权边(但没有负权环),Dijkstra无法直接使用。

核心思路

Johnson算法的核心思路是重赋权:先通过一次 Bellman-Ford 计算出一个”势函数” h,然后利用 h 将所有边权调整为非负值,同时保证调整后的图中任意两点间的最短路径与原图相同。这样就可以安全地对每个顶点运行 Dijkstra 算法了。

2.2 重赋权技术

重赋权(Reweighting)

给定带权有向图 和权函数 重赋权是指定义一个新的权函数 (本文记为 ),使得:

  1. 对所有顶点对 的一条路径是==按 的最短路径当且仅当它是 的最短路径==
  2. 对所有边

如果满足以上两个条件,就可以在重赋权后的图上运行 Dijkstra 算法来求解所有结点对的最短路径。

重赋权的关键方法:

  1. 添加超级源点:构造一个新图 ,其中 是新增的超级源点, 到每个顶点 的边权为 0
  2. 运行 Bellman-Ford:在 上以 为源点运行 Bellman-Ford 算法,计算 (从 的最短路径权重)
  3. 定义新权函数:对原图 中的每条边 ,定义
  4. 删除超级源点:从 中删除 及其关联边,得到重赋权后的图

直觉理解重赋权

想象每个顶点 v 有一个”海拔高度” h(v)。从高处走到低处,实际距离会被”海拔差”补偿,使得调整后的距离始终非负。就像下山时虽然实际走了很远的路,但因为海拔降低,“等效距离”不会变成负数。而任意路径的总调整量只取决于起点和终点的海拔,与中间经过哪些顶点无关,因此最短路径的选择不会改变。

2.3 正确性引理

引理23.1:重赋权后的边权非负

引理23.1(重赋权后的边权非负)

不包含负权环,则对 中所有边 ,有

证明:

考虑 中从超级源点 到任意顶点 的最短路径。由最短路径的三角不等式(参见22.5 最短路径性质的证明),对任意边

即:

移项得:

引理23.2:重赋权保持最短路径

引理23.2(重赋权保持最短路径)

是一个不含负权环的带权有向图, 为其权函数, 为任意函数。对任意路径 ,有:

因此, 中从 的最短路径,当且仅当 中从 的最短路径。

证明:

将路径 计算权重:

展开求和:

第一个求和就是 。观察后两个求和:

【望远镜求和(中间项全部抵消)】 两者相减,中间项 全部抵消,只剩下:

【偏移量仅取决于起终点(与中间顶点无关)】 由于 只取决于路径的起点和终点,与路径的中间顶点无关,因此对于从 的所有路径, 之间相差同一个常数

【常数偏移不改变路径相对长短】 这意味着:如果路径 比路径 更短(),那么按 也更短()。因此最短路径的选择不受重赋权影响。

关键洞察

重赋权的精妙之处在于:路径权重的变化量只取决于起点和终点,与路径长度无关。这意味着无论路径经过多少个顶点,重赋权对每条路径的”偏移量”都是相同的。因此,比较两条路径的相对长短时,这个偏移量会相互抵消,最短路径的选择不会改变。

2.4 Johnson算法伪代码

算法执行流程

  1. 添加超级源 s,s 到所有顶点添加权重为 0 的边
  2. Bellman-Ford 计算从 s 出发的最短路径距离 h(v)
  3. 若存在负权环则报告并终止
  4. h(v) 重赋权:w’(u,v) = w(u,v) + h(u) - h(v)
  5. 对每个顶点 u,用 Dijkstra 在重赋权图上计算最短路径
  6. 还原原始权重:d[u][v] = d’[u][v] - h(v) + h(u)
    A["添加超级源 s, 连接所有顶点(权重0)"] --> B["运行 Bellman-Ford 计算 h(v)"]
    B --> C{"存在负权环?"}
    C -- 是 --> D["报告错误并终止"]
    C -- 否 --> E["重赋权: w'(u,v) = w(u,v) + h(u) - h(v)"]
    E --> F["对每个顶点 u 运行 Dijkstra"]
    F --> G{"还有下一个 u?"}
    G -- 是 --> F
    G -- 否 --> H["还原距离: d[u][v] = d'[u][v] + h(v) - h(u)"]
    H --> I["返回距离矩阵 d"]
JOHNSON(G, w)
1  G' ← (V' = G.V ∪ {s}, E' = G.E ∪ {(s, v) : v ∈ G.V})
2  for each vertex v ∈ G.V
3      w(s, v) ← 0
4  if BELLMAN-FORD(G', w, s) == FALSE
5      error "图包含负权环"
6  for each vertex v ∈ G.V
7      h(v) ← s.d          // h(v) = δ(s, v) 在 G' 中
8  for each edge (u, v) ∈ G.E
9      w'(u, v) ← w(u, v) + h(u) - h(v)
10 for each vertex u ∈ G.V
11     run DIJKSTRA(G, w', u) to compute d'[u][v] for all v ∈ G.V
12     for each vertex v ∈ G.V
13         d[u][v] ← d'[u][v] + h[v] - h[u]
14 return d

算法流程详解:

阶段1(第1-7行):计算势函数

  • 构造 :在原图基础上添加超级源点 到每个顶点添加权为0的边
  • 运行 Bellman-Ford:计算从 到每个顶点 的最短路径权重
  • 如果 Bellman-Ford 返回 FALSE,说明原图包含负权环,算法终止并报错

阶段2(第8-9行):重赋权

  • 对原图每条边 ,计算新权
  • 由引理23.1,所有

阶段3(第10-11行):运行V次Dijkstra

  • 对每个顶点 ,以 为源点在重赋权后的图上运行 Dijkstra
  • 得到 :按 的最短路径权重

阶段4(第12-13行):恢复原始距离

  • 由引理23.2,
  • 因此

2.5 正确性定理

定理23.3(Johnson算法的正确性)

若图 不包含负权环,则 Johnson 算法返回所有顶点对之间的最短路径权重。

证明:

由引理23.1,重赋权后所有边权非负,因此 Dijkstra 算法可以正确运行。

由引理23.2,对任意顶点对 中从 的最短路径按 也是最短路径。因此 Dijkstra 计算出的 满足:

其中 是原图中从 的最短路径权重。

由第13行的恢复操作:

因此 确实等于原图中的最短路径权重。

2.6 复杂度分析

时间与空间复杂度

时间复杂度:

  • 阶段1(Bellman-Ford):
  • 阶段2(重赋权):
  • 阶段3( 次 Dijkstra):
  • 阶段4(恢复距离):
  • 总计:

空间复杂度: (存储距离矩阵

2.7 与Floyd-Warshall算法的对比

对比维度Johnson算法Floyd-Warshall算法
时间复杂度
空间复杂度
稠密图
稀疏图
负权边处理支持(通过重赋权)原生支持
负权环检测支持(Bellman-Ford阶段)需额外检查
实现复杂度较高(组合两个算法)较低(单一动态规划)
并行化困难(V次串行Dijkstra)较易(矩阵运算可并行)

选型建议

对于稀疏图(如道路网络、社交网络),Johnson算法在理论上更优。对于稠密图(如完全图),两者复杂度相当,Floyd-Warshall 由于实现简单且易于并行化,通常是更好的选择。在实际工程中,还需考虑图的规模、是否需要负权支持、以及是否需要并行计算等因素。


补充理解

3.1 Johnson算法的历史

Donald B. Johnson 与1977年论文

Johnson算法由 Donald B. Johnson 于1977年在论文 “Efficient algorithms for shortest paths in sparse networks” 中提出,发表在 Journal of the ACM 上。该论文的核心贡献是提出了重赋权技术,将Bellman-Ford和Dijkstra两个看似不兼容的算法优雅地结合在一起。

参考来源:

  • Johnson, D. B. (1977). Efficient algorithms for shortest paths in sparse networks. Journal of the ACM, 24(1), 1-13. JSTOR
  • NIST DADS: Johnson’s algorithm

3.2 重赋权技术的数学本质

重赋权与势函数

Johnson算法中的 本质上是一个势函数(potential function)。这一思想在数学和物理学中有深刻的类比:

  • 物理学类比:在重力场中,物体从高处移动到低处会获得动能。 类似于每个顶点的”势能”, 类似于”等效距离”。重力势能的变化只取决于起点和终点的高度差,与路径无关——这与重赋权保持最短路径的性质完全对应。

  • 差分约束系统:重赋权技术与22.4 差分约束与最短路径有密切联系。差分约束系统中的变量可以看作势函数,约束 正是最短路径三角不等式的体现。

  • 对偶理论:在线性规划的对偶理论中,重赋权对应于对原始问题添加对偶变量(势函数),从而将约束条件转化为更易处理的形式。

3.3 与A*算法的关系

Johnson重赋权与A*启发函数

Johnson算法的重赋权思想与A*算法的启发函数有深刻的相似性:

  • A*算法使用启发函数 估计从顶点 到目标点的距离,优先队列的key为
  • Johnson算法使用势函数 修改边权为

两者都利用了对目标距离的估计来引导搜索或修改图的性质。区别在于:

  • A* 的 是对到目标的距离的估计,用于引导搜索方向
  • Johnson 的 是从超级源点的最短距离,用于消除负权边

参考来源:Brilliant - Johnson’s Algorithm

3.4 实际应用场景

Johnson算法的应用

  1. 路由表预计算:在网络路由中,需要预先计算所有路由器对之间的最短路径。对于稀疏的网络拓扑(如互联网的AS级拓扑),Johnson算法比Floyd-Warshall更高效。

  2. 社交网络分析:在社交平台中,用户之间的关注/好友关系通常形成稀疏图。利用Johnson算法可以计算所有用户对之间的最短关系链长度,用于推荐系统、社区发现等。

  3. GPS导航预处理:虽然实时导航通常使用A*或其变种,但在离线预处理阶段,可能需要计算路网中所有关键节点对之间的距离。对于稀疏的道路网络,Johnson算法是一个可行的选择。

  4. 物流路径规划:在物流配送中,配送中心与所有配送点之间可能存在负成本(如返程补贴),Johnson算法可以正确处理这种含负权边的情况。

参考来源:CSDN - 从原理到实战:一文吃透Johnson算法


易混淆点

4.1 Johnson vs Floyd-Warshall:如何选型?

4.2 重赋权为什么能保持最短路径?

4.3 为什么需要Bellman-Ford而非Dijkstra来计算h?

4.4 超级源点的必要性

4.5 0权环上的边重赋权后为0


习题精选

题号题目描述难度
23.3-1使用Johnson算法求图25.2中所有顶点对的最短路径,展示 的值⭐⭐
23.3-2添加新顶点 的目的是什么?
23.3-3若所有边权非负, 之间有什么关系?
23.3-4教授Greenstreet提出一种更简单的重赋权方法,有什么问题?⭐⭐
23.3-5证明若 包含0权环 ,则 上每条边的 都为0⭐⭐

视频学习指南

资源主题链接说明
MIT 6.006 Lecture 18All-Pairs Shortest Pathshttps://www.youtube.com/watch?v=KXzJ7dXsNnUMIT完整讲解Johnson算法
Abdul BariJohnson’s Algorithmhttps://www.youtube.com/watch?v=XmS47a5jKzY逐步动画演示
WilliamFisetJohnson’s Algorithmhttps://www.youtube.com/watch?v=09cJvHlOiMg系列讲解,含伪代码
GeeksforGeeksJohnson’s Algorithmhttps://www.geeksforgeeks.org/johnsons-algorithm/文字+图示详解
洛谷日报Johnson全源最短路径算法https://www.luogu.com.cn/article/eew64dlc中文详解,含代码实现

教材原文

CLRS 第4版 23.3节原文(对应第3版25.3节)

Johnson’s algorithm finds shortest paths between all pairs in time. It is a combination of the Bellman-Ford algorithm and Dijkstra’s algorithm. First, it adds a new vertex with zero-weight edges from it to all other vertices, and runs the Bellman-Ford algorithm to check for negative-weight cycles and find , the least weight of a path from the new node to node . Next it reweights the edges using the nodes’ values. Finally for each node, it runs Dijkstra’s algorithm on the reweighted graph.

If the graph contains a negative-weight cycle, Johnson’s algorithm detects this during the Bellman-Ford phase and reports that no solution exists. Otherwise, the algorithm returns a matrix of shortest-path distances for all pairs of vertices.

CLRS 第4版 23.3节原文(重赋权引理)

If contains no negative-weight cycles, then for every edge , the reweighted edge has nonnegative weight: .

A path is a shortest path from to using weight function if and only if is also a shortest path from to using weight function .

教材原文参考

完整原文请参阅《算法导论(第4版)》第23章第3节,或原始素材目录中的PDF文件。


参见Wiki

概念页尚未创建

以下概念页待后续补充:

  • Johnson算法 — 独立概念页
  • 重赋权技术 — 核心技术概念
  • 势函数 — 数学背景概念
  • 所有结点对的最短路径 — 问题定义概念

第23章-所有结点对的最短路径 稀疏图的Johnson算法