Skip to content

算法Algorithm

最小费用流的费用缩放

Cost scaling minimum-cost flow · Epsilon scaling · Goldberg–Tarjan cost scaling

逐次减半约化费用误差,以饱和、推送和降势把伪流恢复为可行流,并给出容量数值无关的阶段操作界。

一份可行流可能还存在很小的负环。费用缩放允许暂时保留一点负约化费用,先解决较粗的误差,再逐步收紧。每个阶段内部也允许顶点暂时有积压或亏缺;阶段结束时必须恢复原来的供需。费用误差与流量守恒是两项分别追踪的条件,任何一项尚未恢复,都不能把状态作为最终解交付。

形式陈述 ​

ε 最优性与严格终止门槛 ​

输入沿用最小费用流的有限容量模型,另给一份满足需求 b 的可行流。费用为整数;容量和初始流可以是精确有理数。保留平行、反平行和自环的独立身份。令

e(v)=流入(v)−流出(v)−b(v),cp(u,v)=cf(u,v)+p(u)−p(v).

中间伪流只要求容量合法,允许 e≠0。对每条正残量记录保持

cp(u,v)≥−ε.

若流已经可行且 nε<1,任何简单环长至多 n,费用不小于 −nε>−1。环费用是整数,故不存在负环,当前流最优。这一推理要求费用整数,容量整数与否无关。[1,Theorem 3.2.1]

初始取零势及不小于 C=maxa|ca| 的二次幂误差,因正反费用绝对值均不超过 C,任意可行起点都满足误差约束。C=0 时该起点已经最优。否则不断调用下面的阶段,把误差减半,直至严格满足 nε<1。

一个阶段的三种操作 ​

阶段入口有可行流 f¯、势 p¯,误差为 2ε。先把当前误差改为 ε,并饱和全部负约化费用残量记录。产生的反向记录约化费用为正,所以此刻所有剩余残量记录费用非负,已满足更强的零误差;代价是产生正负超额。

此后把 e(u)>0 的顶点叫活跃点。对活跃点执行:

  • Push。 如果正残量记录 u→v 的约化费用严格为负,推送 Δ=min{e(u),rf(u,v)}。源超额减少,终点超额增加,新反向记录费用为正。
  • Relabel。 若活跃点没有这样的出记录,降低其势至
p(u)←maxa:u→v, v≠u, rf(a)>0{p(v)−cf(a)−ε}.

Relabel 与当前弧放电扫描都排除自环。自环费用中的势相消:负费用方向已在阶段开始送满,非负费用方向不影响超额;把零自环放入最大值会得到含旧 p(u) 的伪候选,不能保证打开出路。排除自环后,这次赋值会让至少一条非自环出记录费用恰好为 −ε。公式中的候选必非空,因为阶段入口有可行比较流,活跃点必能沿残量记录到达某个亏缺点。用可达集净流入求和即可证明这一事实。

反复执行至没有活跃点。超额总和始终为零,所以此时每个点超额都为零;阶段交出原需求下的可行流及更精确的势。

两个关键不变量 ​

Relabel 前全部残量出记录满足 cp≥0,因而本次势至少降低 ε。出记录由最大值公式保持 cp≥−ε,入记录的约化费用只会增加,故误差约束不被破坏。Push 只增加费用为正的反向记录,同样保持该约束。

把负约化费用的正残量记录组成许可图。初始饱和后许可图没有边。Push 只会删去许可弧,不会增加反向许可弧;Relabel 可能增加从 u 出发的许可弧,但旧入弧费用至少为 −ε,本次又增加至少 ε,所以Relabel 后没有许可弧进入 u。于是许可图始终无有向环。这不是声称整个残量图无环,而是只针对负约化费用子图。[1,Lemmas 3.4.1–3.4.3]

直觉

某条弧约化费用为负,表示按当前价格把流送过去有利。先全部送满,把这种局部有利选择变成各站点的积压与亏缺。活跃点只沿仍有利的方向搬运;无路可搬时,就降低自己的价格,直到至少打开一条许可出路。

降势并不是无界地“降到能走为止”。后面的比较流论证给出每个阶段的总降幅上限,许可图的无环性再控制小推送的次数。因此容量即使有很大分母,算法也不靠每次至少搬动一单位来终止。

降势、许可弧与超额更新

图中只画局部的弧 20,30,10;平行弧 21 与断开分量仍参与执行器计算。边旁标的是残量 ID 与约化费用,最后一格的反向弧表示本次推送新产生的两单位余量。

例子与边界

一个局部放电可以手算 ​

终结任务初始在 s→t 上送三单位、费用七。第一阶段 ε=4,先沿其反向残量记录退回三单位,于是 e(s)=3,e(t)=−3。此时 s→a 有费用一、容量二的弧 20,以及费用二、容量二的平行弧 21;s→t 的正向费用仍为七。

零势下没有负出弧,所以对 s 降势:三个候选依次为 −1−4=−5、−2−4=−6、−7−4=−11,最大值为负五。降势后,弧 20,21,10 的约化费用依次是 −4,−3,2。沿 20 推两单位,得到 e(s)=1,e(a)=2,e(t)=−3。这仍是伪流,不能因为找到有利路径就结束。

同一实例的六个完整阶段 ​

执行器按输入弧次序扫描,活跃点用 FIFO 队列,结果如下。这里 Push 不包括阶段开头的饱和操作。

阶段误差 Push 次数 Relabel 次数 阶段末费用
4 6 4 17
2 7 6 −2
1 3 3 −3
1/2 4 4 −3
1/4 3 3 −3
1/8 5 3 −3

六点满足 6⋅(1/8)<1,此时才由整数费用门槛自动证明最优。虽然第三阶段已经碰到最优费用,算法并不知道这一事实,仍继续收紧。第一阶段甚至把退回的直达流重新送上直达弧,只保留负自环收益;这不违反误差合同,也不要求每个局部操作都降低原始费用。

零费用自环不能决定 Relabel ​

两点环有 s→t 费用一百、t→s 费用负一百零一,容量均一;另有 s 的零费用自环,初始流为零。阶段误差六十四,先饱和负弧,得到 e(s)=1,e(t)=−1。正确 Relabel 在非自环候选 −164,−165 中取 −164,立即打开约化费用负六十四的 s→t。若纳入零自环的伪候选 p(s)−64=−64,降势后自环仍为零,其他出弧仍为正,便违反“一次降势打开一条许可弧”的合同。附件把这项作为显式回归。

等号处确有负环 ​

两点环的弧费用为负一和零,容量均一,取零流、势 (0,−1/2)。两条正残量记录约化费用都是 −1/2,所以 ε=1/2 合法,且 nε=1。但整个环费用仍为负一,可以送一单位改善。终止判断必须严格,不能写成 nε≤1。

若费用改为任意有理数,即使 nε<1 仍可能存在费用 −1/100 的环。可先清除费用分母后用整数门槛,但阶段数要按清分母后的费用位长计算。若用浮点容差代替严格负号,许可图、精确饱和及最优证书都需要重新解释,本页执行器拒绝浮点输入。

推论与应用

为什么每点只能降势 O(n) 次 ​

固定本阶段入口的可行流 f¯ 和势 p¯,它们满足 2ε 约束。任一时刻,当前伪流 f 的正超额点 v 都能通过“把 f 改回 f¯”的差额支撑,到达一个负超额点 w。选择简单路径 P,长度 ℓ≤n−1。路径正方向属于当前残量图,反方向属于 f¯ 的残量图:

c(P)+p(v)−p(w)≥−ℓε,−c(P)+p¯(w)−p¯(v)≥−2ℓε.

亏缺只在阶段初始化产生;Push 的源始终非负,接收端超额只会增加。因此一个此时仍亏缺的 w 从未成为活跃点,也从未降势,p(w)=p¯(w)。相加得到

p(v)≥p¯(v)−3(n−1)ε.

每次 Relabel 至少降低 ε,所以每点每阶段至多 3(n−1) 次。这个界以当前正超额和入口可行比较流为基础,与容量大小无关。[1,Lemmas 3.4.4–3.4.6]

推送次数怎样支付 ​

同一记录方向两次饱和 Push 之间,必须先沿反方向退流;退流要求反方向费用为负,正方向因此为正。要重新沿正方向 Push,只有尾点进一步降势才可能使其再次为负,邻点降势只会让该方向费用增加。因此饱和 Push 总共 O(nm) 次。

非饱和 Push 会把源点超额清零,却不删除许可弧。用势能法,令 R(v) 为许可图中从 v 可达的顶点数,计入 v 自身;取势能为所有活跃点的 R(v) 之和。许可图无环,沿 u→v 有 R(u)≥R(v)+1。一次非饱和 Push 移除活跃源 u,至多增加活跃终点 v,所以势能至少减少一。

饱和 Push 至多新激活一个点,使势能增加至多 n。Relabel 后无人能经许可弧进入被改标点,其他点的可达集不能增加;只有该点的项可能增加,增幅至多 n。结合 O(n2) 次 Relabel 和 O(nm) 次饱和 Push,非饱和 Push 总数为 O(n2(m+n))。[1,Lemma 3.4.8]

当前弧、初始化和位成本 ​

附件为每个顶点保存当前邻接位置。检查失败后向后推进,只有本点 Relabel 才重置;邻点降势会使该出记录费用增加,反向 Push 新开的出记录费用为正,所以跳过的记录不会无故变成新的许可弧。每个阶段所有邻接重扫和 Relabel 的取最大值扫描共 O(nm+n),加上实际 Push 和 FIFO 管理,时间为 O(n2(m+n)+n+m)。

共需 O(1+log⁡(nC+2)) 个阶段。最终的 ε 势未必让每条残量费用非负;若要交付旧模型的零误差势证书,再用一次全图Bellman–Ford求势,计入 O(n+nm)。总工作空间为 O(n+m);保存逐操作超额快照的 trace=True 另付每次 O(n) 输出,audit=True 每步扫描全残量图并检查许可图无环,均不计入核心运算界。

整数费用和二分误差使势为二进制有理数,阶段内总降幅受上界控制。容量若为有理数,可以统一分母理解流和超额的编码长度;精确加减、比较与最小值的位成本仍须另计。上述操作界不依赖容量的数值或分母,不等于对任意长度输入都只花常数位操作。

与容量缩放的选择边界 ​

容量逐位缩放始终维护精确非负约化费用,通过容量位数限制修复总量;本页保持原容量,通过费用位数限制 ε 阶段,阶段内部的流可以有任意正负超额。已有整数容量但有理费用时,前者可直接运行;有理容量但整数费用时,后者可直接运行。

手算迁移:在两点门槛反例中把容量都改成 1/3,比较“每次至少推一单位”为什么失效,而本页的降势和许可图计数为何仍成立。随后运行终结任务,给出全部阶段末的容量、守恒和误差检查,不能只报最后的费用数字。

参考资料
  • Andrew V. Goldberg、Eva Tardos、Robert E. Tarjan,Network Flow Algorithms,1990,§3.2 pp.128、§3.3 pp.128–129、§3.4 pp.129–133、§3.5 p.133:整数费用门槛、generic refine、许可图无环、势下降和推送计数。
  • Andrew V. Goldberg、Robert E. Tarjan,Finding Minimum-Cost Circulations by Successive Approximation,Mathematics of Operations Research 15(3),1990,pp.430–466,DOI:逐次精化的费用缩放框架。
  • Serge Plotkin,Stanford CS361B,Advanced Algorithms Lecture Notes,2014,§5 pp.30–31:ε 势条件与逐次精化的框架;本页采用作者重印本中的完整局部 Push/Relabel 实现与计数。
关系图谱7 个相邻概念 · 3 类关系

拖动节点调整位置。

显示关系

显示:依赖

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