本篇主要讲解最大流问题的Ford-Fulkerson解法。可是说这是一种方法,而不是算法,因为它包含具有不同运行时间的几种实现。该方法依赖于三种重要思想:残留网络,增广路径和割。本文将会详细介绍这些内容。

在介绍着三种概念之前,我们先简单介绍下Ford-Fulkerson方法的基本思想。首先需要了解的是Ford-Fulkerson是一种迭代的方法。开始时,对所有的u,v属于V,f(u,v)=0(这里f(u,v)代表u到v的边当前流量),即初始状态时流的值为0。在每次迭代中,可以通过寻找一个“增广路径”来增加流值。增广路径可以看做是从源点s到汇点t之间的一条路径,沿该路径可以压入更多的流,从而增加流的值。反复进行这一过程,直到增广路径都被找出为止。

举个例子来说明下,如图所示,每条红线就代表了一条增广路径,当前s到t的流量为3。

当然这并不是该网络的最大流,根据寻找增广路径的算法我们其实还可以继续寻找增广路径,最终的最大流网络如下图所示,最大流为4。

接下来我们就介绍如何寻找增广路径。在介绍增广路径之前,我们首先需要介绍残留网络的概念。

一、残留网络

顾名思义,残留网络是指给定网络和一个流,其对应还可以容纳的流组成的网络。具体说来,就是假定一个网络G=(V,E),其源点s,汇点t。设f为G中的一个流,对应顶点u到顶点v的流。在不超过C(u,v)的条件下(C代表边容量),从u到v之间可以压入的额外网络流量,就是边(u,v)的残余容量(residual capacity),定义如下:

r(u,v)=c(u,v)-f(u,v)

举个例子,假设(u,v)当前流量为3/4,那么就是说c(u,v)=4,f(u,v)=3,那么r(u,v)=1。

我们知道,在网络流中还有这么一条规律。从u到v已经有了3个单位流量,那么从反方向上看,也就是从v到u就有了3个单位的残留网络,这时r(v,u)=3。可以这样理解,从u到v有3个单位流量,那么从v到u就有了将这3个单位流量的压回去的能力。

我们来具体看一个例子,如下图所示一个流网络

其对应的残留网络为:

二、增广路径

在了解了残留网络后,我们来介绍增广路径。已知一个流网络G和流f,增广路径p是其残留网络Gf中从s到t的一条简单路径。形象的理解为从s到t存在一条不违反边容量的路径,向这条路径压入流量,可以增加整个网络的流值。上面的残留网络中,存在这样一条增广路径:

其可以压入4个单位的流量,压入后,我们得到一个新的流网络,其流量比原来的流网络要多4。这时我们继续在新的流网络上用同样的方法寻找增广路径,直到找不到为止。这时我们就得到了一个最大的网络流。

三、流网络的割

上面仅仅是介绍了方法,可是怎么证明当无法再寻找到增广路径时,就证明当前网络是最大流网络呢?这就需要用到最大流最小割定理。

首先介绍下,割的概念。流网络G(V,E)的割(S,T)将V划分为S和T=V-S两部分,使得s属于S,t属于T。割(S,T)的容量是指从集合S到集合T的所有边(有方向)的容量之和。如果f是一个流,则穿过割(S,T)的净流量被定义为f(S,T)。将上面举的例子继续拿来,随便画一个割,如下图所示:

割的容量就是c(u,w)+c(v,x)=26

当前流网络的穿过割的净流量为f(u,w)+f(v,x)-f(w,v)=12+11-4=19

显然,我们有对任意一个割,穿过该割的净流量上界就是该割的容量,即不可能超过割的容量。所以网络的最大流必然无法超过网络的最小割。

可是,这跟残留网络上的增广路径有什么关系呢?

首先,我们必须了解一个特性,根据上一篇文章中讲到的最大流问题的线性规划表示时,提到,流网络的流量守恒的原则,根据这个原则我们可以知道,对网络的任意割,其净流量的都是相等的。具体证明是不难的,可以通过下图形象的理解下,

和上面的割相比,集合S中少了u和v,从源点s到集合T的净流量都流向了u和v,而在上一个割图中,集合S到集合T的流量是等于u和v到集合T的净流量的。其中w也有流流向了u和v,而这部分流无法流向源点s,因为没有路径,所以最后这部分流量加上s到u和v的流量,在u和v之间无论如何互相传递流,最终都要流向集合T,所以这个流量值是等于s流向u和v的值的。将s比喻成一个水龙头,u和v流向别处的水流,都是来自s的,其自身不可能创造水流。所以任意割的净流量都是相等的。

万事俱备,现在来证明当残留网络Gf中不包含增广路径时,f是G的最大流。

(下面的证明有点问题,看不懂,之后写一个好点儿的)

假设Gf中不包含增广路径,即Gf不包含从s到v的路径,定义S={v:Gf中从s到v存在一条通路},也就是Gf中s能够有通路到达的点的集合,显然这个集合不包括t,因为s到t没有通路。这时,我们令T=V-S。那么(S,T)就是一个割。如下图所示:

那么,对于顶点u属于S,v属于T,有f(u,v)=c(u,v)。否则(u,v)就存在残余流量,因而s到u加上u到v就构成了一条s到v的通路,所以v就必须属于S,矛盾。因此这时就表明当前流f是等于当前的割的容量的,因此f就是最大流。

四、 Ford-Fulkerson代码实现:

就以上面的流网络为例,实现Ford-Fulkerson算法并测试

#include <iostream>
#include <memory.h>
#include <climits>
#include <algorithm>
#include <vector> using namespace std; #define POINTNUM 7 //源点、汇点
int s, t; //流网络的邻接矩阵表示
int flowMap[POINTNUM][POINTNUM]; //标记走过的点
bool used[POINTNUM]; //打印增广路
//vector<int> path; int fordFulkerson(int s, int t, int flow)
{
int ret = ;
if (s == t)
return flow;
used[s] = true;
for (int i = ; i < POINTNUM; i++)
{
if (!used[i] && flowMap[s][i] > )
{
//确定增广路上的最大流量
int f = min(flow, flowMap[s][i]);
ret = fordFulkerson(i, t, f);
if (ret > )
{
//修改当前图中的流量
flowMap[s][i] -= ret;
flowMap[i][s] += ret;
//path.push_back(i);
return ret;
} }
}
return ret;
} int main()
{
//初始化整个流网络
memset(flowMap, , sizeof(flowMap));
//1 代表s,最后一个点代表t
s = ;
t = ;
int u = ;
int v = ;
int w = ;
int x = ;
flowMap[s][u] = ;
flowMap[s][v] = ;
flowMap[u][v] = ;
flowMap[v][u] = ;
flowMap[u][w] = ;
flowMap[w][v] = ;
flowMap[v][x] = ;
flowMap[x][w] = ;
flowMap[x][t] = ;
flowMap[w][t] = ; int maxFlow = ; while (true)
{
memset(used, false, sizeof(used));
int tmp = fordFulkerson(s, t, INT_MAX);
if (tmp == )
break;
else
{
/* path.push_back(s);
for (vector<int>::reverse_iterator iter = path.rbegin(); iter != path.rend(); iter++)
{
if (iter == path.rbegin())
cout << *iter;
else
cout << "->" << *iter;
}
cout <<" flow :" << tmp << endl;
path.clear(); */
maxFlow += tmp;
} } cout << maxFlow << endl;
}

加入增广路的输出,结果为:

1->2->3->5->4->6 flow :7
1->2->3->5->6 flow :3
1->2->4->3->5->6 flow :1
1->2->4->6 flow :5
1->3->2->4->6 flow :6
1->3->4->6 flow :1
23

最大流问题Ford-Fulkerson方法(转)的更多相关文章

  1. ACM/ICPC 之 网络流入门-Ford Fulkerson与SAP算法(POJ1149-POJ1273)

    第一题:按顾客访问猪圈的顺序依次构图(顾客为结点),汇点->第一个顾客->第二个顾客->...->汇点 //第一道网络流 //Ford-Fulkerson //Time:47M ...

  2. 图的匹配问题与最大流问题(三)——最大流问题Ford-Fulkerson方法Java实现

    上篇文章主要介绍了Ford-Fulkerson方法的理论基础,本篇给出一种Java的实现. 先借助伪代码熟悉下流程 FORD-FULKERSON(G,t,s) 1 for each edge(u,v) ...

  3. poj 1273 Drainage Ditches(最大流,E-K算法)

    一.Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clove ...

  4. NOIp 图论算法专题总结 (3):网络流 & 二分图 简明讲义

    系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 网络流 概念 1 容量网络(capacity network)是一个有向图,图的 ...

  5. [转] 网络流算法--Ford-Fulkerson方法及其多种实现

    网络流 转载自:http://www.cnblogs.com/luweiseu/archive/2012/07/14/2591573.html 在上一章中我们讨论的主题是图中顶点之间的最短路径,例如公 ...

  6. <转载>ford-fulkerson算法

    原文链接http://blog.csdn.net/ivan_zgj/article/details/51580993 最大流问题常常出现在物流配送中,可以规约为以下的图问题.最大流问题中,图中两个顶点 ...

  7. [Algorithm] Maximum Flow

    Ref MIT: lecture-13-incremental-improvement-max-flow-min-cut/ Ford Fulkerson algorithm for finding m ...

  8. Python小白的数学建模课-19.网络流优化问题

    流在生活中十分常见,例如交通系统中的人流.车流.物流,供水管网中的水流,金融系统中的现金流,网络中的信息流.网络流优化问题是基本的网络优化问题,应用非常广泛. 网络流优化问题最重要的指标是边的成本和容 ...

  9. 【题解】luogu P3386 【模板】二分图匹配

    题面:https://www.luogu.org/problemnew/show/P3386 好像没有人发Ford-Fulkerson,我来一发, 这道题和P2756飞行员配对方案问题方法一样,网络流 ...

  10. mathematical method

    mathematical method 曲线拟合 指数 \(lnY = lna + bX\) 对数 \(Y = blnX + a\) 幂函数 \(lgY=lga+blgX\) 多元线性回归模型 回归分 ...

随机推荐

  1. 计算机中如何表示数字-07IEEE754浮点数标准

    由于不同机器所选用的基数.尾数位长度和阶码位长度不同,因此对浮点数的表示有较大差别,这不利于软件在不同计算机之间的移植.为此,美国IEEE(电器及电子工程师协会)提出了一个从系统角度支持浮点数的表示方 ...

  2. AndroidStudio导入Android-PullToRefresh

    方法已经写到我的微信公众号中,公众号二维码在下面 本人联系方式: 更多精彩分享,可关注我的微信公众号: 若想给予我分享更多知识的动力,请扫描下面的微信打赏二维码,谢谢!: 微信号:WeixinJung ...

  3. Codeforces Round #104 (Div. 1)

    A.Lucky Conversion 题意 给定两个长度为 \(N(N \le 10^5)\) 且由4和7构成的 \(a, b\)串 对 \(a\) 可以有两种操作: 交换两个位置的字符; 改变一个位 ...

  4. spark新能优化之数据本地化

    数据本地化的背景: 数据本地化对于Spark Job性能有着巨大的影响.如果数据以及要计算它的代码是在一起的,那么性能当然会非常高.但是,如果数据和计算它的代码是分开的,那么其中之一必须到另外一方的机 ...

  5. POJ1637 Sightseeing tour (混合图欧拉回路)(网络流)

                                                                Sightseeing tour Time Limit: 1000MS   Me ...

  6. Qt_Window@Qt Command Prompt从命令行创建工程

    #include <QApplication> #include <QLabel> int main(int argc, char *argv[]) { QApplicatio ...

  7. 安装了iis之后,打开默认网站http://localhost/要求输入用户名和密码解决办法

        开始-运行gpedit.msc回车.     计算机配置--管理模板-windows 组件-Internet Exporer-Internet控制面板-安全页-Internet区域:双击登陆选 ...

  8. AssetStore资源名字

    NGUI A Pathfinding Project Pro PlayMaker 2DToolkit Scene Manager UniLOD UniLUA Save Game-JSON+Binary ...

  9. LNMP-查看安装编译时参数

    查看mysql编译参数: cat /usr/local/mysql/bin/mysqlbug | grep CONFIGURE_LINE 查看apache编译参数: cat $apachehome$/ ...

  10. BP神经网络——交叉熵作代价函数

    Sigmoid函数 当神经元的输出接近 1时,曲线变得相当平,即σ′(z)的值会很小,进而也就使∂C/∂w和∂C/∂b会非常小.造成学习缓慢,下面有一个二次代价函数的cost变化图,epoch从15到 ...