线性规划问题
- 线性规划可见单纯形算法
- 网络流:
- 源点与汇点的流量和是相等的
- 网络最大流是指在满足容量约束和流量守恒的条件下,在流网络中找到一个净输出最大的网络流
求解最大网络流
增广路算法
- 主体
- 实流网络和残余网络:实流网络只标记每条边的实际流量,而残余网络中,与网络边同向边是可增量,反向边是实际流量
- 可增广路是一条从源点到汇点的简单路径
- 而求解最大流是在残余网络中找到增广路,然后在实流网络中沿可增广路增流
- 具体增广路增流方案
- 在实流网络中沿着可增广路增流:可增广路上的同向边增加流量d,反向边减少流量d
- 残余网络中,可增广路同向减流d,反方增流d
- 算法步骤:
- 访问数组visited[ ],pre[ ] 记录前驱,最大流maxflow = 0;
- 初始化可行流flow为零,即实流网络中的边全是零流量边,残余网络中全是最大容量边;visited [ ]数组全为零,pre[ ] 数组全是 -1;
- 将源点visited[ ] 设置为 1,然后入队
- 如果队列非空,进入循环
- 在循环中,首先出队首元素,然后在残余网络中遍历与首元素相邻的顶点,如果未被访问则访问之,并visited[ ] = 1,pre[ ] 等于此时的首元素;如果此时找到了汇点,即找到了可增广路,结束此刻循环,否则加入队列中,再继续执行循环结构
- 从汇点开始,利用前驱数组,逆向寻找每一条可增广路的最小流,即增量d
- 在实流网络中增流,残余网络中减流,并且最大流增加d
- 重新执行以上步骤,直到无增广路结束程序
Isap算法
即贴标签,对所有的顶点标记到汇点的最短距离
- 最开始从汇点开始,汇点A的层数记录为0
- 遍历与A相邻的点的层数,计算公式为在A的层数基础上加一即可
- 重复第二步骤,直到到大源点
然后寻找增广路径,按照_floor[ u ] == _floor[ v ] + 1 和 容量大于流量的 的关系寻找u的下一个顶点 - 如果当前顶点无法前进,那么令当前的顶点的高度等于所有相邻顶点的高度的最小值 + 1;如果没有邻接点,那么高度等于节点数,即以后都不再访问此节点;然后退回一步,重新搜索即可
求解最小费用最大流
- 先找最小费用路,然后在该路径中增加流量即可,见博文线性规划–最小费用最大流
- 先找最大流,然后找负费用圈,减小到最小费用
重点讲一下消圈算法
在找到的最大流的网络中寻找负费用圈,找到后,负费用圈同方向加d,反方向减d,d是某路径中的最小可增量。
消除负费圈的目的是,如果在一个流网络中求出了一个最大流,但对于一条增广路上的某两个点之间有负权路,那么这个流一定不是最小费用最大流,因为我们可以让一部分流从这条最小费用路流过以减少费用,所以根据这个思想,可以先求出一个最大初始流,然后不断地通过负圈分流以减少费用,直到流网络中不存在负圈为止。
方案配对问题
- 增加源点与汇点即可,其他与上述求解最大流实现一样
- 匈牙利算法,见博文匈牙利算法 – 匹配问题