• 网络流学习-Ford-Fulkerson


    首先我们先解决最大流问题

    什么是最大流问题呢

    根据我的理解,有一个源点s,汇点t,s可以通过一个网络(雾)流向汇点t

    但是每一条边都有他的最大传输容量限制,那么我们的任务是,如何分配流量使得。。从s流向t的流量最大化

    并且由于流量并不存在损失,所以非常重要的一点是收到的流量与发出的流量都相等,对于除了s,t的任何点来说都要成立,否则我们认为这不科学

    首先该网络图是一个有向图,图中的每条边e,都有对应最大可能的数据传输量c(e),这样就可以把问题转为如下形式

    记每条边对应的实际数据传输量为f(e)

    传输量应满足如下性质,0<=f(e)<=c(e)

    对于任意v属于V{s,t},他们所有点的收到的数据量和发送的数据量相等

    为什么这个是正确的呢,因为如果记出去流量为cf,收到流量为sf,对于除了s,t的每一个点,cfi=sfi,那么最终的和式一定是,cfi+...+cfn=sfi+...+sfn

    每次两边都加上相等的两个值。。或者说一堆等式相加,,最后一定还是一个等式

    目标是最大化从s发出的流量

    首先考虑这样一个贪心算法

    找到一条s到t的只经过f(e)<c(e)的边的路径

    如果不存在满足条件的路径,则结束算法。否则,沿着路径尽可能地增加合法的符合约束的流量f(e),返回第一步

    但是我们知道这样是具有后效性的。。也就是说如果你找了不是最优的路径,那么你不能反悔

    由于是邻接表。。这里可以认为你找到的路径是跟输入同样随机的。。。你怎么能确定你的流量分配路径最优呢

    如何解决这个问题呢。。

    只利用满足f(e)<c(e)的e或者满足f(e)>0的e对应的反向边rev(e),寻找一条s到t的路径

    如果不存在满足条件的路径则结束。否则沿着该路径尽可能地增加流,返回第一步。

    我们称f(e)<c(e)的e和满足f(e)>0的e对应的反向边rev(e)所组成的图为残余网络,并称残余网络上s-t的路径为增广路

    实现方面。。我们可以不记录每条边流过的流量的状态,取而代之的是我们可以直接改变其边的容量c(e)

    记最大流的流量为F,那么Ford-Fulkerson算法至多进行F次dfs,所以其复杂度为O(F|E|)不过这是一个很松的上界

    达到这种复杂度的情况基本不存在。。实际应用还是挺好的。。

    那么我们如何证明上面的做法是正确的呢

    为了证明FF算法所求得的确实是最大流,我们首先介绍割这一概念,所谓图的割,指的是对于某个顶点集合S属于V

    从S出发指向S外部的那些边的集合,记为割(S,VS),这些边的容量之和被称为割的容量。如果有s属于S,而t属于Vs

    (我们在前面已经说过了s是源点,t是汇点)

    那么此时的割又称为s-t割。

    如果将网络中s-t割中所包含的边都删去,也就不再有s到t的路径了,因此可以考虑一下如下问题。

    对于给定网络,为了保证没有从s到t的路径,需要删去的边的总容量的最小值是多少?

    该问题又被称为最小割问题。事实上,这个问题与之前最大流的问题有着很深的联系

    首先,让我们来考虑一下任意的s-t流f(s-t的一条流量路径),和任意的s-t割(S,VS),而这个则是一个边集,前面则是一个路径集合

    因为有f(路径流量集合)的流量=(s的出边的总流量)

    而对v属于S{s}又有(v的出边的总流量)=(v的入边的总流量),为什么不除去t呢。。因为t属于VS

    所以有(f的流量)=s的出边的流量+v的出边的总流量-(s的入边的流量(这一项其实等于0)+v的入边的总容量)

    所以我们合并一下就能发现(f的流量)=S的出边总流量-S的入边总流量

    由于存在VS->S的入边。。所以实际上f的流量=割的容量-前面说的VS->S入边的流量,

    由于我们考虑的流量都是大于零的,所以此时可以推出结论f的流量<=割的容量

    接下来,考虑通过FF算法所求得的流f'。记流f'对应的残余网络中从s可达的顶点v组成的集合为S(注意这里的定义更换)

    因为f'对应的残余网络不存在s-t的路径,因此(S,VS)就是一个割,(深度较深的点VS刚好可能没有连边,然而这也是合法的)

    此外根据S的定义,对包含在割中的边e应该有f'(e)=c(e)这一点我们可以通过S的定义来进行反证

    而对VS到S的边e应该有f'(e)=0,这个怎么证明呢。。如果这个f'(e)!=0,则说明它的反向边的容量S->VS的容量不是满的。。

    如果不是满的我就应该把那个点加入到S集合中来,这与S的定义相矛盾。。

    因此f'的流量=(S的出边的流量(割的流量))-(S的入边的总流量(前面证明了这个部分的流量一定是0))=割的容量

    再由之前的之前的不等式可知(任意f的流量<=割的容量),现在等于割的容量。。就证明了这个流f'就是最大的流了

    于是我们证明了FF算法的正确性,同时还推导出了最大流等于最小割这一重要性质,该性质又被称为最大流最小割定理

    根据该定理我们可以直接利用求解最大流问题的算法来求解最小割问题了。

    由FF算法的正确性可以知道,如果所有边的容量都是整数,那么最大流和最小割也是整数

  • 相关阅读:
    taobao 爬虫基本思路分享
    浅谈python中字典append 到list 后值的改变问题
    滑动验证码验证
    selenium:css_selector定位详解
    01分数规划
    可持久化并查集(草稿)
    后缀自动机求endpos集大小
    伯努利数公式
    HDU 6619 Horse 斜率优化dp
    别人的回文自动机
  • 原文地址:https://www.cnblogs.com/linkzijun/p/6543744.html
Copyright © 2020-2023  润新知