最大流
1. 简介
最大流算法主要分为两大类,一类为增广路算法,一类为预流推进算法。最大流算法解决的是在有向网路图 中计算从源点 到汇点 的最大流量问题,以及最小割容量问题。
- 最小割最大流定理
最大流的值等于 的最小割容量。
2. 增广路算法
-
剩余容量
剩余容量 表示边 的容量与流量之差。 -
增广路
对于一个网络图 ,从图 G 中找到一条从源节点 到目标节点 的路径,且路径上所有边的剩余容量都大于 0 ,则这条路径称为增广路 。 -
残量网络
对于网络图 ,残量网络定义为网络 G 中所有节点和剩余容量大于 0 的边构成的子图,即
2.1 EK 算法
- BFS 寻找增广路,一次 BFS 一次增广
- 每一条有向边都需要构造反向边,因为当前增广路可能不是最优的,后续增广可能需要修改流量流向。
EK 算法复杂度为 ( 为节点数, 为边数)。
1 |
|
2.2 Dinic 算法
可以看出,EK 算法存在以下明显不足:
- 一次 BFS 只增广一次,如果残量网络中还存在增广路则被浪费了。
- 对于已经没有剩余容量的边,EK 算法仍然进行增广判断从而导致时间上的浪费。
层次深度
当前节点到源点的最短路径长度(边权值视为 1 )。
Dinic 算法则巧妙解决了 EK 算法的不足之处:
- 一次 BFS 后使用 DFS 进行多次增广。
- DFS 多次增广过程中,对于已经没有容量的边,采用弧优化的方法巧妙避免重复增广判断。
Dinic 算法的复杂度为 ( 为节点数, 为边数)。在稀疏图上,Dinic 算法和 EK 算法相差不大,但在稠密图上(二分匹配之类的)Dinic的优势很明显。
1 |
|
2.3 ISAP 算法
SAP 算法引入了断层的优化方法:
-
距离
当前节点到汇点的最短路径长度(边权值视为 1 )。类似于 Dinic 算法中的层次深度的计算,不过是在反图上从汇点到源点进行 BFS 。 -
断层
数组用来统计距离为 的节点个数。如果增广到某一距离发现节点数为零,需要重新计算所有节点的距离并计算 gap ;如果重新计算后仍然无法增广,则说明源点和汇点之间出现了断层,此时算法结束。
SAP 算法复杂度为 ( 为节点数, 为边数)。
- ISAP 算法即为 SAP 算法的优化版本,在 SAP 算法基础上加上了当前弧优化和分层优化(即 DFS 后不需要重跑 BFS 来进行分层)。
ISAP 算法复杂度为 ( 为节点数, 为边数)。
1 |
|
3. 预流推进算法
预流推进算法的主要思想是允许水在非源汇点的节点中暂时存储,然后每个节点都尽可能将自身的超额流推送出去,并且保证在算法结束后所有非源汇点的超额流都为0,那这种方案就是合法的。
- 超额流
存储在非源汇点中的流称作这个点的超额流。
3.1 HLPP 算法
HLPP 算法的主要思想如下:
- 对于非源汇点的层次深度,每次选择层次深度最大的节点进行推流;
- 如果节点推流后还有余流,则对该节点重贴标签后抬高其高度,回到上一步骤;
- 直到所有非汇源点的余流都等于零,程序结束。
GAP 优化
- 当出现断层后,直接将断层以上深度的所有节点的层次深度设为 ,使得这些再也无法推流到汇点的节点的余流尽快推送回源点,从而减少重贴标签的操作。
HLPP 算法复杂度为 ( 为节点数, 为边数)。
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!