最近在复习算法 对最大流问题加以学习和总结 配套视频学习效果更加
算法设计与分析_北京航空航天大学_中国大学MOOC(慕课) (icourse163.org)
一.实际背景/应用场景
最大流算法作为算法设计与分析中比较经典的算法 在实际生活和工程中有着广泛的运用
例如
对于西气东输问题 我们将问题抽象建模为 图的模型每个中转点相当于一个节点 我们需要考虑的问题是给每一条边输送多少流量 才能保证输送的流量最多 并充分利用管道的容量(根本目的)
流量 :实际每一条边有多少通量
容量 : 实际能够存储多少流量 也是流量的上界
流量的两个性质
first 容量限制 就是刚才提到的流量不能超过容量
second :流量守恒 :就是说除了源点和汇点 其他所有的节点 流入多少他就会流出多少 不会有剩余
有了上述概念 我们就可以定义最大流问题了
给定一个有向图G 以及G中每条边的容量(最大流量) 我们想要求出最大的流量
也就是s中流出的量 或者是 t汇入的流量
但也要满足两个约束条件
1.每条边不能超过容量限制
2.除源点和汇点之外 其他的点流入等于流出 能量守恒
二.求解问题 算法思想
我们定义了问题 并分析了问题的特点 那么我们应该怎样用合适的方法来解决问题呢?
直观策略
- 首先初始化 让每一条边流量为0 每条边光有容量没有流量 那么总流量就是0
- 找出一条从s到p的路径 第一次选路径的时候 路径随便选 只要满足是联通的就行
并取整个路径中最小的容量作为增加的容量一点点进行增流
比如说这个路径s->v2->v3->t 流量 = min{c(i)} = 11
上图为增流的直观认识
3.1重复步骤2 不断进行寻找直到 无法增加路径流量
比如说这个路径s->v1->v3->v4->t 流量 = min{c(j)} = 5
3.2 重复步骤2 不断进行寻找直到 无法增加路径流量
比如说这个路径s->v2->v1->v3->t 流量 = min{14-11=3(注意是剩余流量),5,10-5 = 5} = 3
那么总流量就由刚才的16增加到了19
改进优化解
但这是这是最优方案吗?显然这不是最优
我们可以看到 图的总流量就是由s边流出的流量之和 这个图里显示就是f = f(s v1) + f(s v2)
尝试增加
我们通过两个图的对比不难发现对于边s v1他的容量没有被充分利用 那么我们是否可以试探性的增加一点点的流量 看他是否仍然满足约束条件?
上图是我们的尝试过程 显然是不可以的
改变一点点的策略
尝试缩减
光采取增加的方式显然是不行的 那么我们也可以适当减少某个流量值 来平衡能量的重新分配所带来的变化 比如这个 我sv1 +1 会导致 v1 v3也增加了1 既然顶点v3不能流出 他的流入量 还增加了1 那么我们不妨减少他的另外一个渠道的流入量也就是减少v2 v3的流量 再由v2的能量守恒 v2 v4的流量同时也需要增加1 v4的守恒可知 增加v4 t的流量 那么我们的总流量就变成了20
和直观策略 不一样的地方是 多增加了缩减的方法
缩减和逆向是等价的 所以我们引入反向边的技术
利用逆向搜索技术改进优化解
大白话:就是引入反向边 来动态判断收缩情况
残存网络
为了快速找到反向边我们引入一种工具 ------ 残存网络
对于这道题的残存网络 正向边代表剩余的容量 例如sv1的剩余容量是7 所以对应残存网络的正向边也是7 sv1的流量是5那么他的逆向边就是5 正向边代表可支配 反向边代表可余付。
增广路径
增广路径是在残存网络上s到t的一条简单路径(没有环) 它帮助我们快速发现可调整的路径 增广路径的寻找可以是任意的 因为之后会进行调整
残存容量
大白话:增广路径上中流量最小的边的权值 如右图 7-2-11-6-6所以是2
官方话 增广路径中残存容量的最小值
三.从直观策略到Ford-Fulkerson算法
既然我们有了上述的技术 我们便可以从直观逐步过渡到Ford-Fulkerson算法
针对传统的直观增加策略 他只能扩充边的流量 但是不能缩减边的容量
Ford-Fulkerson步骤
图片介绍了Ford-Fulkerson算法的基本步骤
过渡思路
算法实例
- 初始化流网络G 并构造 对应的Gf
- 找到一条增广路径 并更新总流量 总流量 = 增广路径上权值最小的边的权值 = 该增广路径上权值最小的边 注意 增广路径的选取是任意的 只需要满足有向边路径的联通性即可 这个实例选取的是11
3.找到增广路径之后 更新残存网络 (为了简化起见 需要时可以省略反向边 保持图的简洁性)
4.不断更新 不断发现新的增广路径
- 直到无法找到新的增广路径 程序结束。
算法分析(时间复杂度)
复杂度也取决于每次增广变化的幅度
极差的情况是|f*|的情况
算法正确性证明
充分性 很简单 反证法 假设存在一条增广路径 则他的流会更长
必要性 怎么建立起这两种桥梁 引入概念割
割
什么是割 :去掉之后图就不会连通
定义 割的容量
流值 = 流出 - 流入
流值定理的证明 能量守恒定律 除了s所有顶点入流量和出流量都是相等的
四 最大流和最小割 && 证明的继续讨论
回到开头的问题 根据实际意义 定义两个新的定义 最大流和最小割
总会有一种划分 总有一种划分 无论怎么走 都需要经过这一条路径断了他就会卡脖子 不论流量多大都超不过他
最大流的流量会小于最小割容量 卡脖子项目
了解了这些 我们继续看正确性的证明
课件上写的很清晰 我不做过多解释了
之后 当我们碰到多源的问题 我们也可以转换成单源的问题 运用等价替换的思想
五.实际操作时的易错点:
1.错误点
在实际操作中,以为残存网络不用画反向边而导致计算错误.
反向边在逻辑上对结果也有作用
2.看点例题
显然是233 然后他的最小割是s1 求最小割的一个比较简单的方法是看最后一次的残存网络和源点 连边就构成了最小割 割里面的点到外面具有最小的流量。
在创作中有些仓促,难免有些错误,希望读者批评指正,也期待同大家一起进步~