文章目录
- 前言
- 参考目录
- 学习笔记
- 1:介绍
- 1.1:最小切分问题
- 1.2:最大流问题
- 1.3:小结
- 2:Ford-Fulkerson 算法(FF 算法)
- 2.1:介绍
- 2.2:问题
- 3:最大流量 - 最小切分定理 maxflow-mincut theorem
- 3.1:流和切分之间的关系
- 3.2:定理以及证明
- 3.3:计算最大流中的最小切分
- 4:运行时间分析
- 4.1:FF 算法问题
- 4.2:整数容量 FF 算法
- 4.3:FF 算法最坏情况
- 4.4:增广路径的选择
- 5:Java 实现
- 5.1:流网络表示
- 5.2:流量网络中的边的 API
- 5.3:Java实现:流量边
- 5.4:流量网络的 API
- 5.5:Java 实现:流量网络
- 5.6:流量网络:邻接列表表示
- 5.7:寻找最短增广路径(BFS)
- 5.8:Java 实现:FF 算法
- 6:应用
前言
本篇是在书本第 4 章学习基础上进行拓展,主要内容包括:问题介绍、Ford-Fulkerson 算法、最大流量 - 最小切分定理、运行分析、算法 Java 实现。
参考目录
- B站 普林斯顿大学《Algorithms》视频课
(请自行搜索。主要以该视频课顺序来进行笔记整理,课程讲述的教授本人是该书原版作者之一 Robert Sedgewick。) - 微信读书《算法(第4版)》
(本文主要内容来自《6.0.4 网络流算法》) - 官方网站
(有书本配套的内容以及代码)
学习笔记
注1:下面引用内容如无注明出处,均是书中摘录。
注2:所有 demo 演示均为视频 PPT demo 截图。
注3:如果 PPT 截图中没有翻译,会在下面进行汉化翻译,因为内容比较多,本文不再一一说明。
1:介绍
1.1:最小切分问题
定义:
定义: st 切分(st-cut)是一个顶点集合的划分,将其分为两个不相交的子集 A 和 B,其中源节点 s 属于集合 A,目标顶点(汇节点) t 属于集合 B。
定义: 这个切分的容量(Capacity)是从集合 A 到集合 B 的所有边的容量之和。
最小 st 切分问题: 找到具有最小容量的切分。
1.2:最大流问题
定义:
定义: st 流(简称流)是一种对边的赋值方案,需满足以下条件:
- 容量约束:每条边的流量必须在0到该边的容量之间,即 0 ≤ 边的流量 ≤ 边的容量。
- 局部平衡:除了源点s和汇点t外,每个顶点的流入流量等于流出流量。
定义: 流的值是指在汇点 t 处的流入流量。
最大 st 流(最大流)问题: 找到具有最大值的流。
1.3:小结
值得注意的事实: 这两个问题是双重的!
2:Ford-Fulkerson 算法(FF 算法)
2.1:介绍
摘自书本《6.0.4.4 Ford-Fulkerson算法》:
在1962年,L.R.Ford 和 D.R.Fulkerson 发明了一种解决最大流量问题的有效方法。它是一种沿着由起点到终点的路径逐步增加流量的通用方法,因此它也是同类算法的基础。在经典文献中它被称为 Ford-Fulkerson 算法,但它也被称为增广路径算法。
初始化:
初始流量为零。
想法:通过增加的路径增大流量
增广路径: 寻找一条从源点 s 到汇点 t 的无向路径,且该路径需要满足以下条件:
- 沿路径上的正向边(即从当前顶点指向路径下一个顶点的边)仍有增加流量的空间(未达到其容量上限);
- 沿路径上的逆向边(即与正向边方向相反的边,在流网络中通常表示反向流动)存在非零流量(即并非为空,可以减少流量)。
第 1 次增广路径:
第 2 次增广路径:
第 3 次增广路径:
第 4 次增广路径:
没有更多的增广路径:
2.2:问题
Ford-Fulkerson 算法:
问题:
- 如何计算最小切分?
- 如何寻找增广路径?
- 如果 FF 算法终止,它是否总是计算出了最大流?
- FF 算法是否总会终止?如果是,会在多少次增广之后终止?
3:最大流量 - 最小切分定理 maxflow-mincut theorem
maxflow-mincut theorem
也被翻译成 最大流 - 最小割定理,本文采用书本的翻译。
3.1:流和切分之间的关系
定义: 对于一个切分集 (A, B),其净流量是通过该割集中从集合 A 到集合 B 的所有边的流量之和减去从集合 B 到集合 A 的所有边的流量之和。
流值引理: 设 f 为任意一个流,(A, B) 为任意一个切分集。则 (A, B) 之间的净流量等于流 f 的值。
直观理解: 这是基于流量守恒原则。
证明: 通过归纳法对集合 B 的大小进行论证。
- 基础情况:当 B = {t} 时。
- 归纳步骤:当将任何顶点从集合 A 移动至集合 B 时,由于局部平衡原理,上述结论依然成立。
推论: 源点 s 的流出流量等于汇点 t 的流入流量,两者都等于流的值。
对应书本命题 E:
弱对偶性:
弱对偶性: 设 f 为任意一个流,并设 (A, B) 为任意一个切分集。
那么,流 f 的值小于等于该切分集的容量。
证明: 流 f 的值 = 切分集 (A, B) 净流量 <= 切分集 (A, B) 总容量。
(=
:流值引理;<=
:流量受容量限制)
3.2:定理以及证明
对应书本命题 F:
3.3:计算最大流中的最小切分
计算由最大流 f 决定的最小切分 (A, B) 的方法:
- 根据增广路径定理,针对当前最大流 f,不存在可以进一步增广的路径。
- 计算集合 A:它是由所有通过一条不包含满容量正向边或空容量逆向边的无向路径与源点 s 相连的顶点组成的集合。
4:运行时间分析
4.1:FF 算法问题
问题:
- 如何计算最小切分? (Easy.)
- 如何寻找增广路径? (BFS.)
- 如果 FF 算法终止,它是否总是计算出了最大流? (Yes.)
- FF 算法是否总会终止?如果是,会在多少次增广之后终止?
(Yes,前提是边容量是整数 (或者仔细选择增强路径);需要巧妙分析)
4.2:整数容量 FF 算法
关键特性: 边的容量为介于 1 和 U 之间的整数。
不变式: 在整个 FF 算法过程中,流的值均为整数值(每条边上的流量都是整数)。
证明(通过归纳法):
- 找到的瓶颈容量为整数。
- 对于每条边,其流量在增广过程中会按瓶颈容量整数单位增加或减少。
命题: 增广次数不超过最大流的值。
证明: 每次增广都会至少使流的值增加 1。
整数性定理(对于某些应用场景极为关键): 存在一个整数值的最大流。
证明: 由于 FF 算法最终会停止运行,并找到一个整数值的最大流。
对应书本推论:
4.3:FF 算法最坏情况
坏消息: 即使边的容量为整数,增广路径的数量也可能恰好等于所求最大流的值。
初始状态:
第 1 次增广路径:
第 2 次增广路径:
第 3 次增广路径:
第 4 次增广路径:
……
第 199 次增广路径:
第 200 次增广路径:
结束。
好消息: 这种情况很容易避免。[可以使用最短/最宽路径算法]
4.4:增广路径的选择
在选择增广路径时要慎重考虑。
- 某些选择会导致指数级时间复杂度的算法。
- 明智的选择则会导向多项式时间复杂度的算法。
选择增广路径算法:
- 最短路径算法:边数量最小。
- 最宽路径算法:最大瓶颈容量。
5:Java 实现
5.1:流网络表示
流边数据类型: 为边 e = v → w
定义一个数据结构,其中包含流量属性 fe 和容量属性 ce 。
流网络数据类型: 必须能够处理边 e = v → w
两个方向的信息,即将 e 同时包含在顶点 v 和 w 的邻接表中。
剩余容量:
- 正向边(从 v 到 w):剩余容量 = ce - fe。
- 反向边(从 w 到 v):剩余容量 = fe。
增广流量:
- 正向边(从 v 到 w):增加流量值 ∆。
- 反向边(从 w 到 v):减少流量值 ∆。
剩余网络: 这是一种流网络的有效视角。(包含了所有具有正剩余容量的边)
关键要点: 在原网络中的增广路径与剩余网络中的有向路径一一对应。
对应书本中的说明:
5.2:流量网络中的边的 API
5.3:Java实现:流量边
edu.princeton.cs.algs4.FlowEdge
edu.princeton.cs.algs4.FlowEdge#residualCapacityTo
edu.princeton.cs.algs4.FlowEdge#addResidualFlowTo
5.4:流量网络的 API
5.5:Java 实现:流量网络
edu.princeton.cs.algs4.FlowNetwork
5.6:流量网络:邻接列表表示
5.7:寻找最短增广路径(BFS)
edu.princeton.cs.algs4.FordFulkerson#hasAugmentingPath
5.8:Java 实现:FF 算法
edu.princeton.cs.algs4.FordFulkerson
6:应用
最大流量/最小切分问题是广泛应用于多种问题解决模型的一种方法。
- 数据挖掘
- 露天采矿规划
- 二分匹配
- 网络可靠性分析
- 棒球联赛淘汰赛制分析
- 图像分割技术
- 网络连通性研究
- 分布式计算问题
- 统计数据安全保护
- 平等稳定婚姻匹配问题
- 多摄像机场景重建
- 国土安全传感器布局设计
- ……
(完)