交互式图论学习
交互式图论学习
Guest User
Using app without sign in
最大流计算器
找到网络中从源到汇的最大流量
选择算法并生成步骤以开始可视化
最大流问题询问在每条边都有容量的网络中,能从源点推送多少物料到汇点。它是组合优化中最通用的模型之一,根据最大流最小割定理,其值等于分隔源汇的最小割的容量。
Ford-Fulkerson 方法在残量图中反复寻找从源到汇的增广路径,残量图是一种记录剩余容量并允许撤销流量的记账结构。沿增广路径推送流量直到不存在为止,即得到最大流。Edmonds-Karp 改进总是沿 BFS 找到的最短路径增广,保证 O(V E 的平方);Dinic 算法用层次图和阻塞流进一步改进。
最大流建模管道与交通吞吐量、用于任务分配的二部匹配、航空机组排班、计算机视觉中的图像分割、棒球淘汰以及项目选择。它是竞赛编程和高级面试中标准的进阶图论主题。
这一族的所有最大流算法本质上是同一个循环:找出一条从源点到汇点、尚有剩余容量的路径,沿它尽可能多地推送流量,然后重复。它们的差别只在于如何挑选这条路径。
最大流(图, s, t):
流量 = 0
构建残量图:正向为 cap(u,v),反向为 0
当残量图中仍存在从 s 到 t 的增广路径 P 时:
瓶颈 = P 上最小的残量容量
对 P 上的每条边 (u, v):
残量[u][v] -= 瓶颈
残量[v][u] += 瓶颈 // 撤销边
流量 += 瓶颈
返回 流量
// Ford-Fulkerson:用 DFS 找 P(任意路径)
// Edmonds-Karp: 用 BFS 找 P(最短路径)那条反向的残量边看上去像是写错了,实际上却不可或缺。它让后来的增广路径能够撤销先前推送的流量,于是算法无需显式回溯就能摆脱早期的错误选择。没有这些撤销边,这个贪心循环会卡在一个并非最优的流量上。
在那个经典的例子上运行 Edmonds-Karp:其中最初的贪心选择必须在后面被撤销。
示例图: 有向容量:S 到 A (10)、S 到 B (10)、A 到 B (2)、A 到 T (4)、B 到 T (9)。
最大流为 13,而最小割是边对 A-T 与 B-T,容量合计 13。两个数字相等并非巧合:这就是最大流最小割定理。
时间: 使用 Edmonds-Karp 时为 O(V·E^2) · 空间: O(V + E)
若路径选择是任意的,Ford-Fulkerson 的复杂度为 O(E 乘以最大流量),因为每次增广至少增加一个单位,而每次寻找路径要花 O(E)。这是伪多项式的,而且确实很糟:当容量达到十亿量级时,它可能需要十亿次增广;若容量为无理数,甚至可能不终止。Edmonds-Karp 通过始终用 BFS 选取最短增广路径解决了这一问题。源点到汇点的距离不会减小,且每条边至多成为瓶颈 V/2 次,这把增广次数限制在 O(VE),总代价限制在 O(V 乘以 E 的平方)。Dinic 借助层次图把增广分阶段成组处理,进一步改进到 O(V 的平方乘以 E),在单位容量图上则为 O(E 乘以根号 V)。
如何选择,主要取决于容量的数量级与图的规模。
| 替代算法 | 以下情况更合适 | 代价 |
|---|---|---|
| Edmonds-Karp | 默认选择。用 BFS 挑路径使复杂度上界与容量数值无关。 | O(V·E^2) |
| Dinic 算法 | 规模更大的图。层次图与阻塞流让它在实践中快得多。 | O(V^2·E) |
| Push-relabel 算法 | 非常大的稠密图,此时最优的渐进表现才是关键。 | O(V^3) |
| Hopcroft-Karp 算法 | 问题其实是二分图匹配,那是单位容量最大流的特例。 | O(E·sqrt(V)) |
| 最小割 | 你要的是瓶颈边而不是吞吐量。同一个计算,换个角度读。 | 与最大流同阶 |