重新认识网络流【悲伤脸

来源:互联网 发布:js给元素添加样式 编辑:程序博客网 时间:2024/05/09 03:23

见识到网络流的诡异题目之后我决定重新复习一下网络流的基本含义、、、于是我翻开了罗剑桥(Orz)的课件、、、
定义:流网络G = (V, E) 是具有如下性质的有向图:
●1. 每条边有一个非负的容量限制(capacity) 。
●2. 有一个特殊的源点(source) ,生产流。
●3. 有一个特殊的汇点(sink) ,消耗流。
流:定义:从源点 s 到汇点 t 的流是对每条边赋予一个
权值,满足如下性质:
● 1. 经过每条边的流量不超过限制:0 <= f(e) <= c[e].
● 2. 除了点 s 和 t 以外的每个点满足流量平衡,即
Σ f(e:(u, v)) = Σ f(e:(v, w))
● 一个流的流量为从 s 流出的流量之和。
简单来讲,流类似于生活中的水流……就把源点s类比为水源,汇点t类比为……蓄水站(=,=)而其它的每个点都是一个“输送点”、、、这些输送点不能存储水、、、相当于你从青藏高原取得了一些雪水想要运回自己家泡茶,这期间会经过一些管道,这些管道有容量限制,也就是说,单位时间内只能通过有限的水,现在你想知道单位时间最大能获得多少水到你家、、、因为你要去急着喝茶、、、
这个问题就是最大流问题、、、
显然,贪心算法是不对的、、、
我们引入一个东西叫做残量网络、、、
对流网络G = (V, E) 和一个流f,我们构造一个残留
网络。原来的点集 V 不变。
● 对原来的每条边 e = (u, v), 设其容量限制是 c[e],而
流 f 经过这条边的流量是 f(e),则这条边对应残留网
络中的两条边:u->v: c[e] – f(e) 和 v->u: f(e)。
也就是说,我们如果在原网络中:f(u,v)+= k,那么在残量网络里,r[u,v]-=k,r[v,u]+=k;即构造反向边、、、[r为残余流量]
● 在残留网络中,若从 s 到 t 的一条路径上经过的边
的权值都是正的,那么可以沿着这条路径增广流量,
称这条路径为增广路(augmenting path)。
简单来讲,就是说如果对当前你的网络状态反应到残量网络中,那么在残量网络里显示的就是:
流过这些管道最多再扩大多少流量、、、
增广路就是可扩大流量的路径、、、
增广就是对这条路径的流量进行扩大、、、而每次能扩大的流量取决于S->T的路径上的最小值。
有一种算法叫做“增广路算法”:每次在残量网络中找一个增广路进行增广,并且建立反向边,直到不能进行增广为止,那么得到的流就是最大流、、、


首先我们先来想反向边为什么是正确的、、、
举个例子:
无标题
显然、、、最大流是2,如果第一次走S->1->T,就没有任何问题,可是它是个程序,我们有可能第一步为S->1->2->T,那么,我们不建立反向边,就会发现没有路可以增广,画出它的残量网络:
无标题2333
嗯,的确没有能从S到达T的路径了、、、
我们考虑建立一条反向边的话就会变成这样:
无标题
再次找S点的增广路时,会发现有一条路径为S->2->1->T的路径,这条路径是可以增广的、、、
对于这个图来说,建立反向边是对的、、、
我们来感性的认识一下对于所有图反向边的正确性、、、
首先对于已有的流f[u,v],有反向边f[v,u] = r[u,v];
如果我们接下来的每一步都没有增广到反向边的话,那么这个是对的,因为反向边并没有用上=,=
那么如果增广到反向边了呢?
我们考虑增广到一条反向边(或者反向路径),会发现,可增广量delta = min{f’ in Residual Network|f’}『其实那个残量网络的英文我是百度翻译的』翻译成人话就是:增广路径中找到一个最小的残余流量,假设一条路径的残余流量分别是1,2,3,4,那么显然我们只能这条路径流量+1。如果增广更多,因为:r[u,v] = c[u,v] - r[v,u],即:一条边的正向边+反向边流量等于容量、、、就会超过容量限制、、、
分两种情况讨论:
1.反向边的流量是其中最小的;
2.反向边的流量不是其中最小的;
对于1:显然我们进行的是这样的操作:
在残量网络中,把反向边的剩余流量变为0,正向边的剩余流量加上原来反向边的流量。
略微冷静思考一下,发现是一种”退流“操作,实际上,流并没有从反向边上走。
增广反向边意味着:
1.正向边的流退回原来的路径,并且加到当前增广路被增广的反向边所在的后半段上、、、
2.反向边之前的增广路径上的流与“之前产生反向边的路径”进行”交换“、、、
仔细解释一下这两句话:
首先我们想到,一条边有反向边,当且仅当这条边被增广过。
那么我们发现,当增广错了的时候,比如刚刚这个图:
无标题
显然不应该增广这条路径、、、
没关系,我们继续从S进行增广、、、
我们找到了路径S->2->1->T,并且发现反向边残量是1,它是最小的。我们先正常增广S->2,这时候发现2 - > 1这个反向边了,我们发现,它当时是因为S->1->2->T这条路径的增广而产生的、、、所以我们增广这个反向边相当于把这条边的流退回去。
问题来了,那么S->1->2->T这条路径,1->2的流是退回去了,但是2->T的流没有退回去。仔细想一想发现不必退回去,实际上这步退流,不仅做了退流,还做了一次“交互流”:
我们可以知道,如果反向边的流量为k,那么原来增广这个反向边的增广路径的流量也为k,而这次我们增广到这个反向边,所以此次的增广路径最大能将这条路径的流量增加k、、、
也就是说,我们此次的增广路径的后半段流量最多增加k,即,我们可以把原来路径到”反向边”(对于原来的当然是正向边……)的一个端点时,不走这条边,而是去走此次增广路径的后半段、、、可以知道,流量也是能达到k的、、、而且,考虑此次的增广路径、、、其实反向边是不存在的,我们走的只不过是原来路径的后半段而已。
也就是说:
我们确实退掉了反向边的流,并且使得这两条路径都达到了通过反向边达到的值走反向边的过程相当于:退流加上路径交换的过程。
上面讨论的是”反向边的流量是其中最小的”反向边建立的正确性,但对于“反向边的流量不是其中最小的”这个的正确性,我们可以把它理解为:退掉一部分流加上路径交换。


我们证明了建立反向边的正确性,接下来我们就要证明增广路算法的正确性、、、
它虽然长着一张“我是正确的算法”的脸、、、
但是很不好证、、、
我来简单的证明一下、、、


预备知识(从学军PPT上搞来的):
以下部分转载自某PPT
将f,c,r的定义域扩展为点集:
点集间的流量和: f(X,Y) =p
即:X中的任意一点与Y中的任意一点组成的所有边上的流量之和.(边的方向为从X中的结点到Y中的结点)
c,r等函数都有类似的定义.(点集间的容量和、点集间的残量网络容量和)
所以:
**结论1:
1. f(X,X) = 0。[流量反对称性]
2. f(X,Y) = -f(Y,X) [流量反对称性]
3. f(X ∪ Y,Z) = f(X,Z) + f(Y,Z)
4. f(X,Y ∪ Z) = f(X,Y) + f(X,Z)**
割的定义:
一个割(S,T)由两个点集S,T组成.
S+T = V
s 属于 S.
t 属于 T.
**结论2:
不包含s和t的点集,于它相关联的边上的流量之和为0.**
简单来讲就是有个点集为X,它到除它以外的点的点集的流量之和为0.
证明:
f[X,V - X] = f[X,V] - f[X,X] = f[X,V] = 0;
这个是我自己的想法、、、
来看高贵的学军中学的证明:
f(X,V) = Σ(x ∈ X)[Σ(y ∈ Y)f(x,y)] = Σ(x ∈ X)[0] = 0;
也就是流量平衡的推广、、、
如果不能理解以上证明:
可以这样想:一个点集不包含S和T,那也就是说,流入它的流等于流出它的流,即:f[含S的集合,X] = f[X,含T的集合],
所以f[X,V] = f[X,X] + f[X,含S的集合] + f[X,含T的集合] = 0;
结论3:任意割的流量等于整个网络的流量.
证明:
f(S,T) = f(S,V) – f(S,S) (由结论1)
= f(S,V) (由结论1)
= f(s,V) + f(S – s,V) (由结论1)
= f(s,V) (由结论2)
= |f| (由|f|的定义)
『ps:ppt上一开始写错了1个字母害得我读了半天……』
**结论4:
网络的流量小于等于任意一个割的容量.**(注意这个与辅助定理3的区别.这里是容量)
即|f| <= c(S,T);
证明:
|f| = f(S,T) = Σ(x∈S)Σ(y∈T)f(x,y)(定义) <=Σ(x∈S)Σ(y∈T)c(x,y)
(流量限制) = c(S,T);
现在我们已经有上述预备知识了,就可以对增广路算法的正确性进行证明了。
要证明这些,即证明:
网络流中三个条件是等价的:
1、f是最大流
2、残量网络中找不到增广路径
3、|f| = c(S,T)
1 - > 2的证明:
如果有增广路径,那么f的就可以再次增广,那么f就不再是最大流了、、、
2- >3证明:
定义 S = s ∪ {v | 在残量网络中s到v有一条路径} ;
T = V - S。
则(S,T)是一个割。
所以|f| = f(S,T)(结论3)
『也就意味着:r(S,T) = 0。』
对于这句话的证明:
假设r(S,T) != 0;则在残量网络中,两个集合有边相连,假设u在S集合,v在T集合,那么u - > v有边,也就意味着S可以通过u到达v,所以v应该在S集合中,这与v在T集合中矛盾。
所以r(S,T) = 0;
那么也就是说:|f| = c(S,T) - r(S,T) = f(S,T) = c(S,T);
1- > 2,2 ->3都证明过了,考虑3 -> 1;
由结论4,我们可以知道|f| <= c(S,T),那么如果|f|不是最大流,必然有更大的流、、、但又因为|f| = c(S,T),所以更大的流一定会超过容量限制、、、
至此,1 -> 2,2 -> 3,3 - > 1,分析完毕,也就意味着这三个条件是等价的。
如果说不能推出2-> 3是正确的,那也就意味着,如果我们找错了一条增广路,它也会达到没有增广路经的效果,而且由于错误的决策导致了不是最大流、、、但是因为没有增广路经也就意味着最大流的出现,所以我们能证明增广路算法的正确性、、、


转载自学军中学幻灯片、、、
『话说为什么我还要给解析啊真是累、、、』
至此我已经重新认识了网络流、、、
至于dinic算法什么的、、、
还是不要分析为好、、、
『然后就是愉快地总结网络流经验的时间啦』

1 0