Ref MIT: lecture-13-incremental-improvement-max-flow-min-cut/


Ford Fulkerson algorithm for finding maximal flow in a flow network:

  • Keep adding flow through new augmenting paths for as long as it is possible;
  • When there are no more augmenting paths, you have achieved the largest possible flow in the network.

Ford Fulkerson最大流算法 (Depth-First)

    -- Aleksandar Ignjatovic version.

左边是Residual flow network,一定要亲自画出来。

(a) 初始状态,通过DFS找一条路径作为augmented path; 可见瓶颈是4,然后得到右图。

【注意,为何这里augmented path的选择是如此方式,是否可以变为最短路径作为更好的选择呢】

(b) 同上。

(c) 同上。

(d) 正向的有权边越来越少;然后画出右图(update后的)的residual flow netowork如下。

     

(e) 这个residual flow netowork貌似已经没有了正向有权边。那么,就可以end了。(d)右就是最终结果,以上是最小割。

良心视频 + 个人补充https://www.youtube.com/watch?v=Z8gcjuS0Vb8&t=393s

此处注意标号(s,8)表示上一个节点是s node,(s,8)允许通过的流量是8。

增广链的选择,从t node的标号倒推所得。

此时,最大流等于最小割。

Follow an arbitrary path until you reach the sink.

Not guaranteed to terminate.

举例演示其繁琐性:

最后一张 右边的1->2 又变回了 初始状态 value=1。

让我们抽出两张对比:

可见,中间的这条边value=1成了瓶颈。导致了i++类似缓慢的递归过程。

Time complexity

O(KE) K=Maximum Flow, E=Edge

Dependency on the flow

最大流最小割定理

  Ref: http://www.cnblogs.com/TreeDream/p/5929429.html

  Ref: https://wenku.baidu.com/view/d9c9b9220722192e4536f6e1.html (良心PPT

割的净流:f = f(2,4)+f(4,3)+f(3,5) = 12+(-4)+11=19   //等于node1的output

割的

多一些例子如下:

可以计算出对于这两种情况净流f(S,T)仍然等于19。  //等于node1的output

割的净流:f = f(2,4)+f(4,3)+f(5,4)+f(5,6) = 12+(-4)+7+4=   //等于node1的output

割的容量:c(2,4)+c(5,4)+c(5,6)=12+7+4=23

割的净流:f = f(1,2)+f(3,2)+f(4,3)+f(5,4)+f(5,6) = 11+1+(-4)+7+4=   //等于node1的output

割的容量:c(1,2)+c(3,2)+c(5,4)+c(5,6)=16+4+7+4=31 (一瞧就不是最小的割)

对于任意一个割的净流f(S,T)一定是小于等于割的容量C(S,T)。那也即是,对于网络的任意一个流f一定是小于等于任意一个割的容量C(S,T)。

而在所有可能的割中,存在一个容量最小的割,我们称其为最小割。(回流最小)

最大流最小割定理 (参考)

对于一个网络流图G=(V,E),其中有源点s和汇点t,那么下面三个条件是等价的:
1. 流f是图G的最大流
2. 残留网络Gf不存在增广路
3. 对于G的某一个割(S,T),此时f = C(S,T)

首先证明1 => 2:

我们利用反证法,假设流f是图G的最大流,但是残留网络中还存在有增广路p,其流量为fp。则我们有流f'=f+fp>f。这与f是最大流产生矛盾。

接着证明2 => 3:

假设残留网络Gf不存在增广路,所以在残留网络Gf中不存在路径从s到达t。
我们定义S集合为:当前残留网络中s能够到达的点。
同时定义T=V-S。//到达不了的点的集合T
此时(S,T)构成一个割(S,T)。且对于任意的u∈S,v∈T,有f(u,v)=c(u,v)。若f(u,v)<c(u,v),则有Gf(u,v)>0,s可以到达v,与v属于T矛盾。
因此有f(S,T)=Σf(u,v)=Σc(u,v)=C(S,T)。

最后证明3 => 1:

由于f的上界为最小割,当f到达割的容量时,显然就已经到达最大值,因此f为最大流。


Edmonds-Karp求最大流算法 (Breadth-First)

核心思想就是不断找增广路,每找到一条增广路,记录增广路中 边流量最少的值 d

然后在当前找到增广路中

    • 每一条正向弧减去d,
    • 每一条反向弧加上d,

当不再找到增广路的时候,就证明当前的总流量已经是最大流;

至于怎样找增广路。。一致认为BFS是最好的方法了。

英伦良心TutorialEdmonds Karp Max Flow Algorithm Tutorial

1. 发现最短路径

Paths:

    • S->1->2
    • S->1->3
    • S->3->4

并顺便记录了每个node的child node。

    • , 3
    • : , 3
    • 3: 4
    • : t
    • 3: 4
    • 4: 2, t

可见,最短路径只是根据BFS找,并没有什么特殊的。

2. 处理最短路径

加了反向边,每一条正向弧减去了15。

Total Flow += 15

3. 寻找最短路径(again)

可见,s->3这次也变为了0边。

Total Flow = 15+4, 第二次迭代结果是19.

4. 寻找最短路径(again)

2->t, s->3都变为了0边,那么最短路径的选择结果便有了改变。

Total Flow = 19+7, 第二次迭代结果是26.

Time complexity 

All vertices in residual graph increase monotonically.

Total number of iterations is O(VE) V=Vertices, E=Edges

Each iteration O(E)

Therefore total runtime O(VE2)


Maximum matching in bipartite graphs

二分图最大匹配

二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图。准确地说:把一个图的顶点划分为两个不相交集 UU 和VV ,使得每一条边都分别连接UU、VV中的顶点。如果存在这样的划分,则此图为一个二分图。二分图的一个等价定义是:不含有「含奇数条边的环」的图。图 1 是一个二分图。为了清晰,我们以后都把它画成图 2 的形式。

匹配:在图论中,一个「匹配」(matching)是一个边的集合,其中任意两条边都没有公共顶点。例如,图 3、图 4 中红色的边就是图 2 的匹配。

      

我们定义匹配点匹配边未匹配点非匹配边,它们的含义非常显然。例如图 3 中 1、4、5、7 为匹配点,其他顶点为未匹配点;1-5、4-7为匹配边,其他边为非匹配边。

最大匹配:一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。图 4 是一个最大匹配,它包含 4 条匹配边。

完美匹配:如果一个图的某个匹配中,所有的顶点都是匹配点,那么它就是一个完美匹配。图 4 是一个完美匹配。显然,完美匹配一定是最大匹配(完美匹配的任何一个点都已经匹配,添加一条新的匹配边一定会与已有的匹配边冲突)。但并非每个图都存在完美匹配。换一个说法:最多有多少互相喜欢的男孩/女孩可以配对儿?这就是最大匹配问题。

一、匈牙利算法

求解最大匹配问题的一个算法是匈牙利算法,下面讲的概念都为这个算法服务。

交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边…形成的路径叫交替路。

增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路(agumenting path)。例如,图 5 中的一条增广路如图 6 所示(图中的匹配点均用红色标出):

增广路有一个重要特点:非匹配边比匹配边多一条。因此,研究增广路的意义是改进匹配。只要把增广路中的匹配边和非匹配边的身份交换即可。由于中间的匹配节点不存在其他相连的匹配边,所以这样做不会破坏匹配的性质。交换后,图中的匹配边数目比原来多了 1 条。

我们可以通过不停地找增广路来增加匹配中的匹配边和匹配点。找不到增广路时,达到最大匹配(这是增广路定理)。

那么,如何在某一时刻/状态 找增广路呢?

匈牙利树一般由 BFS 构造(类似于 BFS 树)。从一个未匹配点出发运行 BFS(唯一的限制是,必须走交替路),直到不能再扩展为止。例如,由图 7,可以得到如图 8 的一棵 BFS 树:

       

这棵树存在一个叶子节点为非匹配点(7 号),但是匈牙利树要求所有叶子节点均为匹配点,因此这不是一棵匈牙利树。

(因为node7,所以不是匈牙利树)

如果原图中根本不含 7 号节点,那么从 2 号节点出发就会得到一棵匈牙利树。这种情况如图 9 所示(顺便说一句,图 8 中根节点 2 到非匹配叶子节点 7 显然是一条增广路,沿这条增广路扩充后将得到一个完美匹配)。

匈牙利算法的要点如下

  1. 从左边第 1 个顶点开始,挑选未匹配点进行搜索,寻找增广路。

    1. 如果经过一个未匹配点,说明寻找成功。更新路径信息,匹配边数 +1,停止搜索。
    2. 如果一直没有找到增广路,则不再从这个点开始搜索。事实上,此时搜索后会形成一棵匈牙利树(Fig.9)。我们可以永久性地把它从图中删去,而不影响结果。
  2. 由于找到增广路之后需要沿着路径更新匹配,所以我们需要一个结构来记录路径上的点。DFS 版本通过函数调用隐式地使用一个栈,而 BFS 版本使用 prev 数组。

过程演示

先从1出发,找增广路,找到1->A 这条路,标记并记录。

从2出发,找到2->B这条路,标记并记录。

从3开始找,发现3所连接边全部被占用,这时进行一个神奇的操作:

    • 从三开始找一条增广路,3 -> A -> 1 -> B -> 2 -> C
    • 下划线要出现在两端(增广路的性质)
    • 有增光路,绿线所示

Finally,在图中将有两种颜色的边删去,留下绿色的边。

性能比较

两个版本的时间复杂度均为O(V⋅E)。DFS 的优点是思路清晰、代码量少,但是性能不如 BFS。

我测试了两种算法的性能。对于稀疏图,BFS 版本明显快于 DFS 版本;而对于稠密图两者则不相上下。

在完全随机数据 9000 个顶点 4,0000 条边时前者领先后者大约 97.6%,9000 个顶点 100,0000 条边时前者领先后者 8.6%, 而达到 500,0000 条边时 BFS 仅领先 0.85%。

二、最大流算法

然而,我们也可以把这个问题当作是最大流问题,如下:(匈牙利算法实际上是对最大流算法的一种改进,提高了效率)

中间部分的节点容量设置为1。

计算二分图最大匹配除了匈牙利算法(Hungarian Algorithm),还可以用最大流(Maximal Flow)。

Link: https://www.youtube.com/watch?v=x2BdRml5lmc


巧妙利用min cuts

(1) 实验与仪器,以获得最大受益为目的挑实验来做

E1 (10) --> I1 (5), I2 (6)

E2 (25) --> I2 (6), I3 (7)

因为:最大净收益 = 所有实验收益 - 相应实验方案割的容量

所以:最大净收益 = 所有实验收益 - 最大流

注意 cut的位置!以下稍作权值调整再做一次练习:

最大净收益(9) = 所有实验收益(20+25) - 最大流(5+6+25)

(2) 断开连接,容量代价最小

任务:以最小的断开link的cost分离attacher and victims的PC.

Sol:找到两者的最大流,即是最小割(所有正向割边的容量和称为割的容量,那个最小容量的割),断在这些属于min cuts的edge即可。

(3) 伤员分配问题

任务:左边building里的伤员需要运送到距离20KM以内的医院。

Sol:左边是building内的伤员数量,右边对应医院的容纳量。

(4) 宴席人员分配问题

任务:左边家庭里的成员坐在安排的宴席餐桌,要求家庭成员不能坐在一起。

Sol:添加右边的到T Node的流,权值即是餐桌能容纳的人数。

[Algorithm] Maximum Flow的更多相关文章

  1. [转载]Maximum Flow: Augmenting Path Algorithms Comparison

    https://www.topcoder.com/community/data-science/data-science-tutorials/maximum-flow-augmenting-path- ...

  2. Maximum Flow Exhaustion of Paths Algorithm

    参考youtube上的视频: http://www.youtube.com/watch?v=sxyCzzUuXLo 笔记: 只要是那条路上为0后,就不会再走那条路. 所以没有S->U->W ...

  3. SPOJ 4110 Fast Maximum Flow (最大流模板)

    题目大意: 无向图,求最大流. 算法讨论: Dinic可过.终于我的常数还是太大.以后要注意下了. #include <cstdio> #include <cstring> # ...

  4. Maximum Flow and Minimum Cut

    最大流最小割 Introduction Mincut Problem 最小割问题,输入是带权有向图,有一个源点 s(source)和一个汇点 t(target),边的权重在这里称作容量(capacit ...

  5. [Algorithm] Maximum Contiguous Subarray algorithm implementation using TypeScript / JavaScript

    Naive solution for this problem would be caluclate all the possible combinations: const numbers = [1 ...

  6. [图论]最大流问题(Maximum flow)的定义

    首先定义网络(network)N =(V,E), V表示顶点(Vertices)集合, E表示边(Edges)集合. s,t是V中的两个顶点,分别表示网络N中的源点(source)和汇点(sink). ...

  7. 【找规律】计蒜客17118 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 E. Maximum Flow

    题意:一张有n个点的图,结点被编号为0~n-1,i往所有编号比它大的点j连边,权值为i xor j.给你n,问你最大流. 打个表,别忘了把相邻两项的差打出来,你会发现神奇的规律……你会发现每个答案都是 ...

  8. 2017年icpc西安网络赛 Maximum Flow (找规律+数位dp)

    题目 https://nanti.jisuanke.com/t/17118 题意 有n个点0,1,2...n-1,对于一个点对(i,j)满足i<j,那么连一条边,边权为i xor j,求0到n- ...

  9. 本人AI知识体系导航 - AI menu

    Relevant Readable Links Name Interesting topic Comment Edwin Chen 非参贝叶斯   徐亦达老板 Dirichlet Process 学习 ...

随机推荐

  1. 应用栈解决迷宫问题的C语言实现

    题目来自于严蔚敏<数据结构>,参考伪代码实现的程序: #include <stdio.h> #include <malloc.h> //记录通道块在迷宫矩阵当中的横 ...

  2. 基于Python的SQLAlchemy的操作

    安装 在Python使用SQLAlchemy的首要前提是安装相应的模块,当然作为python的优势,可以到python安装目录下的scripts下,同时按住shift+加上鼠标左键,从而在菜单中打开命 ...

  3. C语——宏小结

    c语言关于宏的使用十分频繁.但是宏的使用有利也有弊,与此同时,它还是一个特别容易搞错的地方.正是基于此,它常常成为一些面试会侧重考察的地方. 所谓宏就是 #define 机制包括的一个规定,即允许把参 ...

  4. 一段用c#操作datatable的代码

    using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; usin ...

  5. android:View的setTag和getTag

    Adapter 有个getView方法,可以使用setTag把查找的view缓存起来方便多次重用 public View getView(int position, View convertView, ...

  6. ToolTip C#

    yourToolTip = new ToolTip(); //The below are optional, of course, yourToolTip.ToolTipIcon = ToolTipI ...

  7. selenium之关于 chromedriver的安装和使用

    转自:https://blog.csdn.net/d77808675/article/details/79016271 最近在学习爬虫,用到了selenium 环境:Windows,python3 但 ...

  8. Web 安全 之 OpenSSL

    什么是OpenSSL协议? SSL(Secure SocketLayer,安全套接层)协议是使用最为普遍网站加密技术,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技 ...

  9. 微软BI 之SSIS 系列 - 使用 Multicast Task 将数据同时写入多个目标表,以及写入Audit 与增量处理信息

    开篇介绍 在 SSIS Data Flow 中有一个 Multicast 组件,它的作用和 Merge, Merge Join 或者 Union All 等合并数据流组件对比起来作用正好相反.非常直观 ...

  10. Visitor模式和Observer观察者模式

    所谓访问者模式,就是不同服务提供者对同一种服务提供的服务内容不同. Typedef   std::vector<Ivisitable>   VisitbleArray; Typedef  ...