xxx 最小费用最大流问题的 Successive Shortest Path with Potentials 算法
字数 2653 2025-11-30 02:00:43

xxx 最小费用最大流问题的 Successive Shortest Path with Potentials 算法

题目描述
最小费用最大流问题(Minimum Cost Maximum Flow, MCMF)是在一个带权有向图中,每条边有容量限制和单位流量的费用。目标是在满足容量约束的前提下,从源点 \(s\) 到汇点 \(t\) 输送尽可能多的流量,并使得总费用最小。Successive Shortest Path with Potentials 算法是解决该问题的高效方法,通过结合最短路径算法和势函数(Potentials)来消除负权边,从而避免使用效率较低的 Bellman-Ford 算法反复计算最短路径。


解题过程

  1. 问题建模

    • 设图 \(G=(V,E)\),每条边 \(e=(u,v)\) 有容量 \(c(e) \geq 0\) 和费用 \(w(e)\)(可能为负)。
    • 目标:在流量守恒约束和容量约束下,最大化从 \(s\)\(t\) 的流量,最小化总费用 \(\sum_{e} f(e) \cdot w(e)\)
  2. 算法核心思想

    • 算法逐步增加从 \(s\)\(t\) 的流量,每次沿当前残量网络中费用最小的路径(最短路径)推送流量。
    • 关键挑战:残量网络中可能存在负权边(反向边费用为原边的相反数),直接使用 Dijkstra 算法需保证无非负权环。势函数通过调整边权,使所有边权非负,从而允许使用高效的 Dijkstra 算法。
  3. 势函数(Potentials)的作用

    • 为每个节点 \(u\) 分配势 \(\phi(u)\),将边 \((u,v)\) 的权重调整为 \(w_{\phi}(u,v) = w(u,v) + \phi(u) - \phi(v)\)
    • 性质:调整后的路径长度与原路径长度仅差一个常数(\(\phi(s) - \phi(t)\)),因此最短路径不变。
    • 目标:通过选择合适的 \(\phi\),使得所有残量边满足 \(w_{\phi}(u,v) \geq 0\),从而可使用 Dijkstra 算法。
  4. 算法步骤
    初始化

    • 流量 \(f(e) = 0\),总流量 \(F = 0\),总费用 \(Cost = 0\)
    • 势函数初始化为 \(\phi(u) = 0\)(或通过一次 Bellman-Ford 计算,确保初始非负权)。

    主循环(直到无法从 \(s\)\(t\) 推送流量):

    • 步骤 1:在残量网络中使用势函数调整边权:
      对残量边 \(e=(u,v)\),定义调整后权值 \(w_{\phi}(e) = w(e) + \phi(u) - \phi(v)\)
      • \(e\) 为原边且剩余容量 \(c_f(e) > 0\),则权值为 \(w(e)\)
      • \(e\) 为反向边(对应原边流量 \(f(e) > 0\)),则权值为 \(-w(e)\)
    • 步骤 2:在调整后的残量网络上运行 Dijkstra 算法,求从 \(s\) 到所有节点的最短距离 \(d(u)\)(基于 \(w_{\phi}\))。
      • \(t\) 不可达,终止算法。
    • 步骤 3:沿找到的最短路径 \(P\)(从 \(s\)\(t\))推送流量:
      • 推送量 \(\Delta = \min\{ c_f(e) \mid e \in P \}\)
      • 更新路径上每条边的流量:对前向边增加 \(\Delta\),对反向边减少 \(\Delta\)
      • 更新总流量 \(F \leftarrow F + \Delta\),总费用 \(Cost \leftarrow Cost + \Delta \cdot \sum_{e \in P} w(e)\)
    • 步骤 4:更新势函数:\(\phi(u) \leftarrow \phi(u) + d(u)\)
      • 此操作保证下一轮调整后的边权仍非负(关键性质:\(d(v) \leq d(u) + w_{\phi}(u,v)\) 在最短路径树中成立)。
  5. 正确性说明

    • 势函数更新后,对于残量边 \((u,v)\),新权值满足:

\[ w_{\text{new}}(u,v) = w(u,v) + \phi_{\text{new}}(u) - \phi_{\text{new}}(v) = w(u,v) + [\phi(u) + d(u)] - [\phi(v) + d(v)] = [w_{\phi}(u,v)] + [d(u) - d(v)] \geq 0 \]

 因为 $d(v) \leq d(u) + w_{\phi}(u,v)$,即 $w_{\phi}(u,v) + d(u) - d(v) \geq 0$。
  • 因此算法始终在非负权图中运行 Dijkstra,保证高效性。
  1. 复杂度分析
    • 若使用二叉堆实现 Dijkstra,每次找最短路径的时间为 \(O(m \log n)\)
    • 最多推送 \(F_{\max}\)(最大流值)次流量,总复杂度为 \(O(F_{\max} \cdot m \log n)\)
    • 通过势函数避免重复运行 Bellman-Ford,显著优于基础 Successive Shortest Path 算法(后者复杂度为 \(O(F_{\max} \cdot m \cdot n)\))。

实例演示
考虑一个简单网络:

  • 节点 \(V=\{s,a,t\}\),边:
    \((s,a)\):容量=2,费用=1;
    \((a,t)\):容量=2,费用=2;
    \((s,t)\):容量=1,费用=4。
  • 目标:从 \(s\)\(t\) 的最小费用最大流。

执行过程

  1. 初始势 \(\phi=0\),残量网络边权与原图相同。
  2. 第一轮 Dijkstra 找到最短路径 \(s \to a \to t\)(费用和=3),推送流量 \(\Delta=2\),更新费用 \(Cost=6\),更新势 \(\phi(s)=0, \phi(a)=1, \phi(t)=3\)
  3. 第二轮:残量网络中边 \((s,t)\) 权值调整为 \(4 + 0 - 3 = 1\),路径 \(s \to t\) 被选中,推送 \(\Delta=1\),总流量=3,总费用=10。
  4. 终止:残量网络中 \(t\) 不可达,算法结束。

最终结果:最大流=3,最小费用=10。

xxx 最小费用最大流问题的 Successive Shortest Path with Potentials 算法 题目描述 最小费用最大流问题(Minimum Cost Maximum Flow, MCMF)是在一个带权有向图中,每条边有容量限制和单位流量的费用。目标是在满足容量约束的前提下,从源点 \(s\) 到汇点 \(t\) 输送尽可能多的流量,并使得总费用最小。Successive Shortest Path with Potentials 算法是解决该问题的高效方法,通过结合最短路径算法和势函数(Potentials)来消除负权边,从而避免使用效率较低的 Bellman-Ford 算法反复计算最短路径。 解题过程 问题建模 设图 \(G=(V,E)\),每条边 \(e=(u,v)\) 有容量 \(c(e) \geq 0\) 和费用 \(w(e)\)(可能为负)。 目标:在流量守恒约束和容量约束下,最大化从 \(s\) 到 \(t\) 的流量,最小化总费用 \(\sum_ {e} f(e) \cdot w(e)\)。 算法核心思想 算法逐步增加从 \(s\) 到 \(t\) 的流量,每次沿当前残量网络中费用最小的路径(最短路径)推送流量。 关键挑战:残量网络中可能存在负权边(反向边费用为原边的相反数),直接使用 Dijkstra 算法需保证无非负权环。势函数通过调整边权,使所有边权非负,从而允许使用高效的 Dijkstra 算法。 势函数(Potentials)的作用 为每个节点 \(u\) 分配势 \(\phi(u)\),将边 \((u,v)\) 的权重调整为 \(w_ {\phi}(u,v) = w(u,v) + \phi(u) - \phi(v)\)。 性质:调整后的路径长度与原路径长度仅差一个常数(\(\phi(s) - \phi(t)\)),因此最短路径不变。 目标:通过选择合适的 \(\phi\),使得所有残量边满足 \(w_ {\phi}(u,v) \geq 0\),从而可使用 Dijkstra 算法。 算法步骤 初始化 : 流量 \(f(e) = 0\),总流量 \(F = 0\),总费用 \(Cost = 0\)。 势函数初始化为 \(\phi(u) = 0\)(或通过一次 Bellman-Ford 计算,确保初始非负权)。 主循环 (直到无法从 \(s\) 到 \(t\) 推送流量): 步骤 1 :在残量网络中使用势函数调整边权: 对残量边 \(e=(u,v)\),定义调整后权值 \(w_ {\phi}(e) = w(e) + \phi(u) - \phi(v)\)。 若 \(e\) 为原边且剩余容量 \(c_ f(e) > 0\),则权值为 \(w(e)\)。 若 \(e\) 为反向边(对应原边流量 \(f(e) > 0\)),则权值为 \(-w(e)\)。 步骤 2 :在调整后的残量网络上运行 Dijkstra 算法,求从 \(s\) 到所有节点的最短距离 \(d(u)\)(基于 \(w_ {\phi}\))。 若 \(t\) 不可达,终止算法。 步骤 3 :沿找到的最短路径 \(P\)(从 \(s\) 到 \(t\))推送流量: 推送量 \(\Delta = \min\{ c_ f(e) \mid e \in P \}\)。 更新路径上每条边的流量:对前向边增加 \(\Delta\),对反向边减少 \(\Delta\)。 更新总流量 \(F \leftarrow F + \Delta\),总费用 \(Cost \leftarrow Cost + \Delta \cdot \sum_ {e \in P} w(e)\)。 步骤 4 :更新势函数:\(\phi(u) \leftarrow \phi(u) + d(u)\)。 此操作保证下一轮调整后的边权仍非负(关键性质:\(d(v) \leq d(u) + w_ {\phi}(u,v)\) 在最短路径树中成立)。 正确性说明 势函数更新后,对于残量边 \((u,v)\),新权值满足: \[ w_ {\text{new}}(u,v) = w(u,v) + \phi_ {\text{new}}(u) - \phi_ {\text{new}}(v) = w(u,v) + [ \phi(u) + d(u)] - [ \phi(v) + d(v)] = [ w_ {\phi}(u,v)] + [ d(u) - d(v) ] \geq 0 \] 因为 \(d(v) \leq d(u) + w_ {\phi}(u,v)\),即 \(w_ {\phi}(u,v) + d(u) - d(v) \geq 0\)。 因此算法始终在非负权图中运行 Dijkstra,保证高效性。 复杂度分析 若使用二叉堆实现 Dijkstra,每次找最短路径的时间为 \(O(m \log n)\)。 最多推送 \(F_ {\max}\)(最大流值)次流量,总复杂度为 \(O(F_ {\max} \cdot m \log n)\)。 通过势函数避免重复运行 Bellman-Ford,显著优于基础 Successive Shortest Path 算法(后者复杂度为 \(O(F_ {\max} \cdot m \cdot n)\))。 实例演示 考虑一个简单网络: 节点 \(V=\{s,a,t\}\),边: \((s,a)\):容量=2,费用=1; \((a,t)\):容量=2,费用=2; \((s,t)\):容量=1,费用=4。 目标:从 \(s\) 到 \(t\) 的最小费用最大流。 执行过程 : 初始势 \(\phi=0\),残量网络边权与原图相同。 第一轮 Dijkstra 找到最短路径 \(s \to a \to t\)(费用和=3),推送流量 \(\Delta=2\),更新费用 \(Cost=6\),更新势 \(\phi(s)=0, \phi(a)=1, \phi(t)=3\)。 第二轮:残量网络中边 \((s,t)\) 权值调整为 \(4 + 0 - 3 = 1\),路径 \(s \to t\) 被选中,推送 \(\Delta=1\),总流量=3,总费用=10。 终止:残量网络中 \(t\) 不可达,算法结束。 最终结果:最大流=3,最小费用=10。