xxx 最小费用最大流问题(Successive Shortest Path算法)
字数 2262 2025-10-31 12:28:54
xxx 最小费用最大流问题(Successive Shortest Path算法)
题目描述
给定一个带权有向图,其中每条边除了有容量限制(表示最大可流通量)外,还有一个单位流量的费用。目标是在满足流量从源点 \(s\) 到汇点 \(t\) 最大的前提下,使总费用最小。该问题称为最小费用最大流问题(Minimum Cost Maximum Flow, MCMF)。例如,在物流配送中,边容量代表运输能力,费用代表单位运输成本,问题等价于在最大化运输量的同时最小化总成本。
解题过程
1. 问题建模
- 图结构:有向图 \(G=(V,E)\),每条边 \(e=(u,v)\) 有容量 \(c(e) \geq 0\) 和单位费用 \(w(e)\)(流量每增加1单位需付出的成本)。
- 目标:找到流函数 \(f: E \to \mathbb{R}^+\),满足:
- 容量约束:\(0 \leq f(e) \leq c(e)\)。
- 流量守恒:除源点 \(s\) 和汇点 \(t\) 外,每个顶点入流等于出流。
- 最大流:从 \(s\) 到 \(t\) 的流量 \(F\) 最大化。
- 最小费用:总费用 \(\sum_{e \in E} f(e) \cdot w(e)\) 在最大流条件下最小。
2. 核心思想:残量网络与负环消除
最小费用流问题常用Successive Shortest Path(SSP)算法求解,其核心是:
- 残量网络:基于当前流 \(f\) 构建残量图 \(G_f\):
- 对于原边 \(e=(u,v)\),若 \(f(e) < c(e)\),则在 \(G_f\) 中保留正向边,容量为 \(c(e)-f(e)\),费用为 \(w(e)\)。
- 对于反向边 \(e'=(v,u)\),容量为 \(f(e)\),费用为 \(-w(e)\)(用于回流抵消费用)。
- 关键性质:若残量网络中无负费用环,则当前流是最小费用流(对于当前流量值)。
- SSP策略:每次在残量网络中找一条从 \(s\) 到 \(t\) 的最短路径(按费用),并沿该路径推送尽可能多的流量,逐步增加总流量并保持费用最小。
3. 算法步骤详解
步骤1:初始化
- 初始流 \(f(e) = 0\),总流量 \(F=0\),总费用 \(Cost=0\)。
- 构建初始残量网络 \(G_f\)(与原图相同,反向边容量为0)。
步骤2:检查可达性与可行性
- 若 \(s\) 到 \(t\) 在残量网络中不可达,算法终止(已达最大流)。
- 注意:若存在负费用环,需先用Bellman-Ford检测并消除(SSP假设初始无负环)。
步骤3:寻找最短路径
- 在残量网络 \(G_f\) 中,使用Bellman-Ford算法(或允许负权的SPFA)计算从 \(s\) 到所有顶点的最短路径(按费用之和)。
- 记录路径的前驱节点和最短距离 \(d(v)\)。
步骤4:推送流量
- 若存在 \(s \to t\) 的路径,则沿该路径推送流量:
- 路径可推送的流量 \(\Delta = \min\{ \text{路径上边的剩余容量} \}\)。
- 更新路径上每条边 \(e\):
- 正向边:流量增加 \(\Delta\),剩余容量减少 \(\Delta\)。
- 反向边:容量增加 \(\Delta\)(允许后续回流)。
- 更新总流量 \(F \leftarrow F + \Delta\),总费用 \(Cost \leftarrow Cost + \Delta \cdot d(t)\)(因为 \(d(t)\) 是路径费用和)。
步骤5:更新残量网络
- 根据新流更新 \(G_f\) 中边的容量和反向边。
步骤6:重复步骤2–5
- 直到无法找到 \(s \to t\) 的路径(达到最大流),输出 \(F\) 和 \(Cost\)。
4. 正确性保证
- 归纳法:每次增加的路径是当前残量网络中费用最小的,保证在流量逐次增加时,每一步的费用增量最小。
- 无负环假设:算法过程中保持残量网络无负环,避免陷入无限循环或非最优解。
5. 复杂度分析
- 每次迭代使用Bellman-Ford求最短路径,复杂度 \(O(|V||E|)\)。
- 最多需增广 \(F_{\max}\) 次(每次至少增加1单位流量),总复杂度 \(O(F_{\max} \cdot |V||E|)\)。
- 若容量为整数,\(F_{\max}\) 受最大流值限制,但对于大容量可能较慢。实际中常用SPFA或Dijkstra(通过势函数处理负权)优化。
6. 实例演示(简例)
考虑一个简单网络:
- 顶点:\(s, a, t\),边:
- \(s \to a\):容量=2,费用=1
- \(a \to t\):容量=1,费用=2
- \(s \to t\):容量=1,费用=4
- 步骤:
- 初始流为0。
- 最短路径 \(s \to a \to t\),费用=3,推送流量=1(受 \(a \to t\) 容量限制)。
- 更新后,\(a \to t\) 满容量,残量网络中移除 \(a \to t\) 正向边,添加反向边。
- 下一最短路径 \(s \to t\),费用=4,推送流量=1。
- 最大流 \(F=2\),总费用=1×3 + 1×4 = 7。
总结
SSP算法通过逐步增广最短路径,结合残量网络动态调整,在保证流最大的同时最小化费用。其核心在于维护无负环的残量图并高效求解最短路径,是解决最小费用最大流问题的经典方法。