运筹学---最大流问题
简单复习一下最大流问题以及最小费用最大流问题
基本概念
一个赋权有向图称为网络,每个弧
网络上的流是定义在弧集合上的一个函数f,
可行流指的是满足条件
对于发点的流出量等于收点的流入量,称为这个可行流的流量,记为
最大流问题是要求
增广链
增广链是从发点到收点的一条链,满足这个链中正方向的弧
(正向指的是这条弧的方向和链从起点到终点的方向相同,反向反之)
可看到,如果找到一个增广链,就可以调整这个增广链上面的流,让前向弧上的f增加,后向弧上面的f减少,调整的数字相同保证调整后的流仍然是可行流,并且流量增加。
寻取最大流的标号法
从一个可行流出发,不断调整使得这个流的流量增加,直到不能进行。
可行流必定存在,因为零流就是可行流。
调整过程
以下的标号和调整进行一次,就可以找到一条增广链并且将这条增广链上的流量尽量调整到最大
标号和调整不是一劳永逸的,因此每找一条增广链就要重新标号。
标号
思路说明
这是一个图及其上面的可行流,弧上标的是
标号指的是给每个顶点标号,标的什么号?通俗的说是记录从某个前面的点到这个顶点的流入量可以增加的余地(记为
(当然上面说的“流入量”是我瞎编的,字面意思,解释不清,l的具体定义见具体步骤)
一条链中一个顶点的流入量受限于两个因素(important)
- 这个顶点之前的弧的容量
- 这个顶点的前一个顶点的
因为每次调整的目的是找到一条增广链,因此上面说的“增加”指的是这个点相邻的某一条弧上流量增加而导致这条弧流入量的增加,仅仅局限于一条增广链。为了找到这条增广链,同时也要记录影响这个弧的前一条弧。
因此,标号要记录的是我们上面说的l,以及导致l的顶点,为了和书上统一:
具体步骤
- 标记发点为
,这个0没什么意思 - 从已标号的点
开始,对所有相邻的没标号的点 - 如果
是弧,并且这条弧不饱和,就给 标号, - 如果
是弧,并且是非零流弧,就给 标号,
- 如果
- 经过了2 的
称为已检查的,如果所有标号顶点都是已检查的,并且标号进行不下去的时候,就得到最大流,具体解释见后
调整
经过上面的标号步骤,收点也被标上号
在这条增广链上前向弧的流量增加
调整结束后继续转入标号程序
判断已达到最大流
截集及其相关定义
将网络的点集V分为两个集合
截集的流量(截量)
可以证明
判断条件
如图,当标完
所以当前流就是最大流
最小费用最大流
最大流可能有多个,要找到费用最小的最大流
基本定义
单位流量费用
总费用计算公式
思路
首先,零流是对应流量的最小费用流(因为费用都是正的
增广链的费用
增广链的费用指的是这条链的流量增加1,这条链上的费用的增加量,等于
递推
如果
每次都沿着最小费用增广链调整,最终得到的f就是最小费用流
问题转化为如何寻找最小费用增广链
这本质上又是一个最短路问题
要求找到的最短路里面的弧都是非饱和弧或者零流弧
可以构造一个新的图,顶点和原图一样,把原来的每一条弧变成两条方向相反的弧,权为
(或者直接删掉正无穷的这些弧
找到这个图从发点到收点的最短路就得到了最小费用增广链