Skip to content

算法Algorithm

最小费用流的逐次最短路法

successive shortest path · SSP min-cost flow

在残量网络反复沿最短费用路增广,并用顶点势保持约化费用非负。

形式陈述 ​

输入与必须保持的条件 ​

本页求有限容量网络中指定源 s≠t、目标流量 F 的最小费用流。从流值为 F0≤F 的可行流 f0 出发,并要求它已经是该流值下的最小费用流,等价地,其整个残量网络没有负费用环。零流可在原图无负费用环时满足这一条件;“任意可行流”本身不够。

每条原弧保留身份。正向残量容量为 ua−fa、费用为 ca,反向容量为 fa、费用为 −ca。对每条残量记录 b,分别记其残量容量为 rf(b)、残量费用为 cf(b);两者不能混用。维护有限顶点势 π,使所有正残量记录的约化费用

cπ(u,v)=cf(u,v)+π(u)−π(v)≥0.

初始势可用Bellman–Ford求得:加入一个向每点连零费用弧的虚拟源,计算全图距离。若检测到负环,须先更换或优化起始流;此时不能构造全局非负约化费用的势。若已有一份可行势,则可直接使用。

一轮最短增广与势更新 ​

在约化费用上运行Dijkstra,得到源距离 d(v)。若目标不可达而流量仍不足,当前残量网络没有增大流值的方向,所要求的 F 不可行。否则取最短路 P,令

Δ=min{F−|f|, mina∈Prf(a)}>0.

为了让不可达顶点也有合法的势更新,定义

d^(v)=min{d(v),d(t)},π′(v)=π(v)+d^(v),

其中 min{+∞,d(t)}=d(t)。随后沿 P 增广 Δ,正向加流、反向减流。

旧残量记录的非负约化费用与距离三角不等式给出

d^(v)≤d^(u)+cπ(u,v),

所以新约化费用仍非负。若 d(u)≥d(t),右边至少为 d(t);若 d(u)<d(t),则对 d(v) 用普通三角不等式后再截断即可。路径 P 上的前缀距离都不超过 d(t),每条边满足等号,因此新出现的反向记录约化费用也为零。

全局非负约化费用排除了负费用环,故增广后的流仍是其新流值下的最小费用流。达到 F 时,这份不变量直接证明目标最优;只更新当前可达点而声称所有残量边仍非负,则需要额外条件,不能省略不可达分量的检查。

直觉

每轮保留已经作出的费用最优安排,再用当前最低边际费用增加一批流。反向弧允许重排旧路线,节点势则把这种可撤销的费用系统改写成 Dijkstra 可以处理的非负权图。

势不是另一个目标函数。对固定端点,路径约化费用与真实费用只差 π(s)−π(t);排序没有改变。截断距离的作用是把本轮达到目标以后的区域统一抬高,保持整张残量图的价格约束。

约化费用、势与逐路增广

图中四点都可达,距离为 0,1,1,3,均不超过 d(t)=3,所以截断更新恰好就是图上的 π′←π+d。

例子与边界

图中的一轮可以直接复算 ​

图上约化边费为 s→a:1,a→b:0,b→t:2,s→b:4,a→t:5。最短路 s−a−b−t 的约化费用为三,距离依次为零、一、一、三。更新势后,三条路径边的新约化费用都为零;两条旁路分别变为 4+0−1=3 与 5+1−3=3。增广产生的三条反向记录也为零。若路径各有一单位余量且尚缺一单位,就增广一单位。

不可达点为什么也参与全局势 ​

取零势及残量弧 s→v 费用五、x→v 费用零,令目标为 v,而 x 从 s 不可达。若只把可达点的势加上距离,π′(v)=5,π′(x)=0,则 x→v 的新约化费用为负五。截断更新同时令 π′(x)=5,这条边仍为零。这个例子没有负环,错误发生在“全局非负”的不变量,而不是原问题突然不可行。

另一个错误是从任意可行流启动。取容量一、费用零的 s→t,再加一个断开的单位容量环 a→b→a,费用为负二和零。若起始流已在 s→t 送满,目标 F=1 立即满足,但费用零仍可通过填满该环降到负二。可行性归约只保证供需满足,没有自动完成费用优化。

容量与总成本 ​

设 n 为顶点数、m 为原弧数,成功增广 A 次。带句柄二叉堆、邻接表及单位成本精确算术下,每轮最短路、势更新和路径更新为 O((n+m)log⁡(n+1))。计入一次可能失败的末尾搜索,总时间为

O(n(n+m)+(A+1)(n+m)log⁡(n+1)),

首项是显式虚拟源初始化的 Bellman–Ford;若已有可行势,可省去该项。工作空间为 O(n+m)。

若容量、起始流与 F 都为整数,每次至少增加一单位,故 A≤F−F0。按瓶颈批量增广能减少一些实例的轮数,却没有消除这种最坏数值依赖;二进制编码下该界是伪多项式。任意实容量时,每次操作的正确性仍成立,但不能再用“一次至少增加一”证明同一轮数界。

推论与应用

这一过程是原始—对偶方法:流满足当前流值的原始约束,势证明其费用最优,零约化费用路径使两者同步推进。整数容量、非负初始费用的固定流量问题可以从零流、零势开始,这是常见而条件清楚的实现入口。

带下界和多点供需时,应先说明采用哪一种归约。找到任意可行环流之后,还需优化其残量环流,或采用从对偶可行伪流出发、逐步消除超额的另一种 SSP 形式。后者有不同的中间状态,不能把它与本页“每轮都是当前流值的最优可行流”混为一套初始化。

容量逐位缩放给出这种伪流修复的一个完整入口:倍增最优环流后,新出现的负约化费用方向每条只有一个单位余量;饱和它们产生至多m总正超额,再沿最短路补向亏缺点。它复用全图截断势更新,但阶段内不声称流已经满足原始守恒。

达到目标时可输出原弧流量与全局可行势,检查容量、守恒及每条正残量记录的约化费用。若求最小费用最大流,则持续增广到无路,最后另附残量可达割证明流值已最大。

参考资料
  • Ravindra K. Ahuja、Thomas L. Magnanti、James B. Orlin,Network Flows,1993,逐次最短路算法与最优性条件。
  • MIT6.854,David Karger,Minimum Cost Flow Algorithms,Lecture14,§§14.1–14.3:无负环起点、零约化费用路径及一般费用环流的初始化。
  • AtCoder Library,mincostflow.hpp,dual_ref:只处理到目标弹出,并对已结算点更新 π(v)+d(v)−d(t);与本页截断更新相差一个全局常数。该实现要求输入费用非负,本页的 Bellman–Ford 初始化是更一般的入口。
  • Norbert Zeh,Algorithms II,§6.5.2 The Algorithm:从对偶可行伪流出发的多点供需版本,须连同其初始化与符号约定阅读。
关系图谱8 个相邻概念 · 3 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系