最大流的增广路算法(EK)
2017-03-18 11:12
211 查看
首先介绍算法中的一些基本概念:
容量:c(u,v)。表示边 <u,v>最大可以承载的流量。
流量:f(u,v)。表示边 <u,v>中已经有多少流量。
残量:r(u,v)。表示边 <u,v>还可以走多少的流量会达到饱和。r = c – f。
为了理解最大流算法,可以形象的将网络中的各个边联想成水管。那么c和f表示水管内的最大水流量以及水流量。r表示这个水管还能够增加多少单位的水流量。而对于一条路径,其能够增加的最大水流量受限于该路径经过的所有水管中最小的r。
有了这个具象之后,不难理解网络流的三大性质:
1. “水流量”f(u,v)<=”最大水流量”c(u,v)
2. 对于任意一个”水管”,f(u,v) = -f(u,v)。(反对称性)
3. 对于任意一个非源点和宿点的网络结点;流入的水流量一定等于流出的水流量。
要想求出从源点到宿点最大可以流过多少的流量,EK算法的思路很简单,从零流量开始不断地在网络中增加流量,直到没有任意一条从源到宿的路径可以再增加流量为止。而再这个过程中,增加的所有流量和就是可以网络可以承受的最大流。
鉴于以上的分析,总结出EK算法的过程如下:
1. 在网络中求出一条从源到宿的路径。计算该路径能通过的最大流量,记做r’。(求源到宿的路径可以使用BFS)
2. 在网络中将步骤1计算出来的路径流量增加r’,那么每个边的残量r就减少了r’。得到了一个残量网络。(这一步骤称为增广)
3. 在残量网络中重复步骤1,2。直到步骤1不能求出新的路径时,所有r‘的和即为最大流。
假设我们有初始网络如下图:
首先在步骤1中我们得到的路径1->2->3->4。该路径上可以流过的流量为2。得到残量网络如下,图中边上的二元组表示(f,c):
图中有一些奇怪的橙色边,在原始网络中是没有的。这些边称为反向弧。以1->2的反向弧为例,其r = c – f = 0 – (-2) = 2。
那么为什么要设立这些反向弧呢?这个残量网络中,如果只有正向的弧,我们不难发现,已经无法增广了。但是从原始网络中,从肉眼都可以看出最大流为3。如果不继续增广,结果显然不对。
但是在增加了反向弧之后,尚有一条增广路1->3->2->4,流量为1。
首先,在引入反向弧之后,它还是满足网络流的三大性质的,因此,是一个合法的网络流。其次,两个流1->2->3->4和1->3->2->4,相加之后可以理解为整个网络在2->3边上走了一个单位流量。
EK算法在得到一条增广路之后,求残量网络都是以路径能够承受的最大流量去算的。而这个最大的流量配出去之后不一定就是对的。那么反向弧的设立为之前配错的流量提供了一个可以反悔的机会。
EK算法编码如下:
执行可得,结果为3。
容量:c(u,v)。表示边 <u,v>最大可以承载的流量。
流量:f(u,v)。表示边 <u,v>中已经有多少流量。
残量:r(u,v)。表示边 <u,v>还可以走多少的流量会达到饱和。r = c – f。
为了理解最大流算法,可以形象的将网络中的各个边联想成水管。那么c和f表示水管内的最大水流量以及水流量。r表示这个水管还能够增加多少单位的水流量。而对于一条路径,其能够增加的最大水流量受限于该路径经过的所有水管中最小的r。
有了这个具象之后,不难理解网络流的三大性质:
1. “水流量”f(u,v)<=”最大水流量”c(u,v)
2. 对于任意一个”水管”,f(u,v) = -f(u,v)。(反对称性)
3. 对于任意一个非源点和宿点的网络结点;流入的水流量一定等于流出的水流量。
要想求出从源点到宿点最大可以流过多少的流量,EK算法的思路很简单,从零流量开始不断地在网络中增加流量,直到没有任意一条从源到宿的路径可以再增加流量为止。而再这个过程中,增加的所有流量和就是可以网络可以承受的最大流。
鉴于以上的分析,总结出EK算法的过程如下:
1. 在网络中求出一条从源到宿的路径。计算该路径能通过的最大流量,记做r’。(求源到宿的路径可以使用BFS)
2. 在网络中将步骤1计算出来的路径流量增加r’,那么每个边的残量r就减少了r’。得到了一个残量网络。(这一步骤称为增广)
3. 在残量网络中重复步骤1,2。直到步骤1不能求出新的路径时,所有r‘的和即为最大流。
假设我们有初始网络如下图:
首先在步骤1中我们得到的路径1->2->3->4。该路径上可以流过的流量为2。得到残量网络如下,图中边上的二元组表示(f,c):
图中有一些奇怪的橙色边,在原始网络中是没有的。这些边称为反向弧。以1->2的反向弧为例,其r = c – f = 0 – (-2) = 2。
那么为什么要设立这些反向弧呢?这个残量网络中,如果只有正向的弧,我们不难发现,已经无法增广了。但是从原始网络中,从肉眼都可以看出最大流为3。如果不继续增广,结果显然不对。
但是在增加了反向弧之后,尚有一条增广路1->3->2->4,流量为1。
首先,在引入反向弧之后,它还是满足网络流的三大性质的,因此,是一个合法的网络流。其次,两个流1->2->3->4和1->3->2->4,相加之后可以理解为整个网络在2->3边上走了一个单位流量。
EK算法在得到一条增广路之后,求残量网络都是以路径能够承受的最大流量去算的。而这个最大的流量配出去之后不一定就是对的。那么反向弧的设立为之前配错的流量提供了一个可以反悔的机会。
EK算法编码如下:
#-*- coding: utf-8 -*- topo = { 1 : {2 : 2, 3 : 1}, 2 : {1 : 0, 3 : 2, 4 : 2}, 3 : {1 : 0, 2 : 0, 4 : 2}, 4 : {2 : 0, 3 : 0} } INF = 0xFFFFFFFF def ek_bfs(s, t): flag = [0 for i in range(len(topo) + 1)] return ek_bfs_core(flag, s, t, INF) def ek_bfs_core(flag, s, t, r): flag[s] = 1 if s == t: return r for node, cap in topo[s].items(): if flag[node] == 0 and cap > 0: new_r = ek_bfs_core(flag, node, t, min(r, cap)) if new_r != 0: topo[s][node] -= new_r topo[node][s] += new_r return new_r return 0 def ek(s, t): total_f = 0 while True: f = ek_bfs(s, t) if f == 0: break total_f = total_f + f return total_f if __name__ == '__main__': print ek(1, 4)
执行可得,结果为3。
相关文章推荐
- 网络流初步 增广路算法求最大流 hdoj3549
- 网络最大流中一般增广路算法(标号法)
- 网络最大流求解 增广路算法
- 网络流初步——增广路算法(EK)模板
- 最大流DFS(EK)算法模板
- POJ 1459 PowerNetwork 多源点网络流入门(EK算法求最大流)
- HDOJ1532 最大流 BFS + EK 算法 模板
- 最大流-EK(Edmond—Karp)算法
- POJ1273 Drainage Ditches【最大流、增广路算法Edmonds_Karp】
- Power Network--最大流的EK()算法
- poj1459Power Network_最大流的增广路算法_多源点多汇点问题(Edmord_Karp)
- PKU 2584 - T-Shirt Gumbo (二分图最大匹配 & 匈牙利算法 | 最大流 & EK)
- poj 3436 最大流的增广路算法
- POJ3436--ACM Computer Factory--拆点EK算法求最大流
- 匈牙利算法求二分图的最大匹配寻找增广路的几种思路(转)
- 最大流(增广路-EK)poj1273
- EK(BFS)求最大流的算法模板(邻接表)
- Power Network (最大流增广路算法模板题)
- 网络最大流增广路模板(EK & Dinic)
- 【二分匹配】【匈牙利算法即由增广路求最大匹配模板】