Skip to content
NotesAlgorithm

算法设计与分析课程笔记,覆盖分治、图算法、最短路与复杂度基础。

Shortest Path (Negative) & Bellman-Ford

一、 负权最短路径问题与 Dijkstra 的失效溯源

1.1 带负权图与负权环 (Negative Cycle)的挑战

  • 问题拓展:当有向图 G(V,E) 允许边的权重 w(u,v) 为负数时,路径长度依然定义为权重的代数和。
  • 距离无穷小危机:如果图中存在负权环 (Negative Cycle)(即一个环上所有边权加起来 <0),那么我们可以通过无限制地绕着该闭环走,使总距离变得“只有更小,没有最小”。在这种情况下,最短距离在数学上处于未定义 (Not well-defined) 状态。

1.2 Dijkstra 算法在负权图下的破产

  • 寻找反例 (Finding a counter example): 假设图中有源点 s,存在路径 sa 权重是 5,路径 sba 权重是 73=4。 Dijkstra 的策略是贪心锁定最近的点。当它看到 a 距离为 5,而 b 距离为 7 时,它会毫不犹豫地宣布“到达 a 的全局最短距离已确定为 5”,并将 a 这颗棋子彻底钉死在已知最短路径集合 T 中不再理会。然而,它万万没想到后面竟然躲藏着一条负权的大道 (b,a),使正确的答案应当是 4。
  • 指出证明中的问题 (Pointing out problems in the proof): 回忆上一节课中 Dijkstra 正确性证明的核心逻辑: 假设新纳入节点 v 存在另一条更短路径 sxvx 是路径上刚出圈的界外节点。因为距离只会越走越长(前提是边权 0),所以必然有 distT(x)真实路线总长<distT(v),进而推导出应该先选择 x 入圈的矛盾。 而在负权图中,这一逻辑链条在“距离越走越长”处彻底崩塌。即使当前看起来 distT(x)distT(v) 大,路径在经过随后的负权边时,完全可能再次把总长度“拉低”到 distT(v) 以下!由于丧失了这一单调增长性保障,假定自然被撕裂。

二、 Bellman-Ford 算法的绝地反击

2.1 算法出发点 (Intuition)

  • 从“聪明”到“粗暴”:Dijkstra 极度聪明,它精心编排了一套正确的探索顺序,确保全图只有一轮有效操作,每条边恰好只起一次松弛作用。但在负权肆虐的无序世界中,这套最优顺序彻底无解。
  • 核心策略:“蠢方法破局” 既然无法预知最佳的收敛节点次序,那么算法的最高哲学退化为大巧不工——全面遍历,循环松弛 (Keep updating everyone!)。不再费心挑选具有极值的人选,而是用所有的边,对所有的节点,轮番检查并更新其当前已知距离,不给遗漏死角留机会。

2.2 基础伪代码雏形

text
// 算法:Bellman-Ford 雏形
// 输入:允许带负权的有向图 G(V, E), 源点 s
Function bellman_ford(G, s):
    dist[s] = 0
    for each x in V (x != s):
        dist[x] = infinity
    // 只要有任何顶点的距离还能变得更短,就不停地用所有边去松弛
    while 存在 dist[x] 被成功更新:
        for each 边 (u, v) in E:
            dist[v] = min(dist[v], dist[u] + w(u, v))

2.3 图的适用性分析 (Graph Applicability)

对于 Bellman-Ford 算法,我们需要明确它所解决的图域范围:

  • 什么样的图能让 Bellman-Ford 正确计算?(What kind of graphs make it correct?)
    • 答案不包含负权环 (Graphs without negative cycles) 的图。只要没有负权环,该算法一定能收敛并得出所有点的正确最短路径。
  • 为什么我们只需要考虑这种没有负权环的图?(Why we only need to consider this kind of graphs?)
    • 答案:因为一旦图中出现了负权环,最短路径在数学上已经不再是良定义 (Not well-defined) 了。我们可以绕着负权环走无数圈,使得路径的总权重变得“要多小有多小”(The shortest distance can be as small as we want!)。因此,对于包含负权环的图,提问“最短路径是多少”本身就是失去意义的。

三、 正确性推导与核心边界条件

面对这种依靠暴力的策略,我们需要严密的数学来为其刻画收敛边界。

3.1 核心引理与数学归纳法 (Lemma 1)

  • 引理 1:经过 k 轮全图松弛后,dist(v) 绝对等同于所有“包含不超过 k 条边的路径”中的真正最短距离。
  • 证明 (Induction)
    • 边界状态 (Base Case):经过 0 轮松弛时,dist[s]=0。0 条边的路径只能停留在源头,因此正确。
    • 递推假设 (Inductive Step):假定经过 k1 轮后,各点 dist 都已经收敛到了不超过 k1 条边路径的最优解。
    • 考虑存在一条由 k 条边构成的通向 v 的最短路径:(s,u1,u2,,uk1,v)
    • 根据前述假设可知,在第 k1 轮结算后,dist[uk1] 这个前驱位置的最小距离(由 k1 边支撑)无论如何是已经准确算得的:dist[uk1]d(s,u1,,uk1)
    • 随后步入了第 k 轮松弛循环。由于 Bellman-Ford 算法每次无差别清点并且使用了网络中所有的 (u,v) 去实施探测与刷新,那它就绝对涵盖了并测试了具体的边 (uk1,v)
    • 结果:通过执行 dist[v]=min{dist[v],dist[uk1]+w(uk1,v)} 补全了那最后的第 k 块拼图。由于囊括所有的可能前趋 uk1k 步的最短路径理论自然得证。

3.2 终极收敛定律与边界判定 (Observation 2)

  • 定律 2:在一切不包含负权环的图网络里,任取任意一对正常节点,他们之间真正的最优最短路径(必须是没有环的简单路径),其所包含的边数上限绝不可能突破 |V|1 这条红线。
  • 推论:如果路径一旦包含了整整 |V| 条边甚至更多呢?这意味着途经了至少 |V|+1 个节点,由鸽巢证明必现重复节点,进而表明必然踏上了一个环路。只要这个环路不是负权环,剔除这圈长跑完全能够取得更短的路径结果。
  • 黄金收敛点 (Conclusion):将引理 1 和定律 2 融合,只需要死磕 |V|1 轮,全图中所有点的最短路径就已经触达了其所能下潜的最深边界,此后绝不会再泛起任何涟漪。

3.3 负权环探测机制 (Negative Cycle Detection)

此时我们发现了该算法的一个致命且极其美妙的附带价值:测谎

  • 如果在执行完 |V|1 轮的定局后,我们刻意再让全体边去跑第 |V| 轮松弛。
  • 若此时竟然还有节点的 dist[v] 发生了松动下降!这说明什么?这说明产生了一条 >|V|1 条边的路径打破了原有的常伦最优解;这也等同宣布图中真真切切潜伏这一个罪恶的负权环 (Negative Cycle),正凭借其绕圈机制无底线地缩短距离!

3.4 Bellman-Ford 最终版伪代码精调

text
Function Modified_Bellman_Ford(G, s):
    // 1. 初始化
    dist[s] = 0
    dist[x] = infinity (for x != s)
    
    // 2. 锁定执行 |V|-1 轮核心拓展
    for i from 1 to |V| - 1:
        for each 边 (u, v) in E:
            dist[v] = min(dist[v], dist[u] + w(u, v))
            
    // 3. 执行第 |V| 轮全图探雷,捕捉负权环
    for each 边 (u, v) in E:
        if dist[u] + w(u, v) < dist[v]:
            return "存在负权环 (Negative Cycle)!"
            
    return dist // 所有图内普通点最短路径已经完美计算完毕

四、 复杂度分析

相比 Dijkstra 的灵活多变,Bellman-Ford 返璞归真。

  • 运行时间总揽
    • 两层极其规整的嵌套循环作为整个算法的主轴。
    • 外层循环 i[1,|V|] 次数恒定为 |V| 次。
    • 内层循环需要轮询图中所有的边,耗时等比例切合于 O(|E|)
    • 时间复杂度始终严丝合缝锁定为:$$O(|V| \cdot |E|)$$
  • 利弊权衡 (Trade-Off)
    • 在密集图或者全连通网路中,这种简单纯粹导致其退化至恐怖的 O(|V|3)(相对于带有 Fibonacci Heap 的优先队列 Dijkstra 极速版 O(|V|log|V|+|E|) 是非常缓慢的)。
    • 但是,它打破了负权禁制,将算法的健壮性抬升到了最高维度。只要不存在负环,不管图中带有多少负数,它都能强硬地暴力砸开黑盒计算到底;一旦隐藏负环,它也能精准鸣笛示警。