最大流最小割
Introduction
Mincut Problem
最小割问题,输入是带权有向图,有一个源点 s(source)和一个汇点 t(target),边的权重在这里称作容量(capacity),是个正数。
st-cut(cut): 把图的点分成两个集合 A 和 B,源点 s 和汇点 t 分别属于集合 A 和 B。
capacity: 从集合 A 的点指向集合 B 的点的边的权重之和,如下图。
最小割问题就是找到使 capacity 最小的划分(st-cut),即阻隔从源点到汇点的最小代价。课程举了一个军事补给线的例子,可以用于找到切断敌方军队补给的最小代价。
Maxflow Problem
最大流问题,输入差不多,边一样有容量,多了个流(flow)的概念。把边想象成水管,容量就是设计的最大的流量,流就是实际的流量,显然后者不能大于前者。
为了简化问题,我们假定源点只有流出量,汇点只有流入量,二者相等,也是这张图流的值(总流量)。对于图中的点来说,除了源点和汇点,流入量和流出量是一样的,净流量为零。最大流问题即找出从源点通过图能够传到汇点的最大流的值,满足边的容量限制,各个点要怎么分配流量。应用例子可以反着来,通过补给线能给前线最大提供多少补给,又该怎么调配。
令人惊讶的是,最大流问题和最小割问题是对偶的(dual),若前者有最优解,则后者的最优解存在且相等。
Ford-Fulkerson Algorithm
Ford-Fulkerson 算法是一类计算网络流的最大流的贪心算法,按增广路径的寻找方式又有几种不同的实现方式。
大致过程: 将图中的边视作无向的,边的流量初始为 0,然后寻找从源点 s 到汇点 t 的增广路径,在路径上:
- 增加容量未满的正向边上的流量。
- 减少流量非空的反向边上的流量。
增广路径即存在未满正向边或非空反向边的路径,正向边即边的方向和路径一样,反向边反之。增加源点到汇点方向的正向边流量,减少相反方向的反向边流量,直到没有增广路径,感觉上也是最后就能算出最大流。看个例子:
这条源点到汇点的路径上有很多容量未满的正向边,还有条流量非空的反向边。为了知道增加(减少)多少流量,我们需要计算正向边剩余的可用容量以及反向边被占用的流量,从中找出最小值。上图中不难看出