网络最大流量与载量容量的关系

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络最大流量与载量容量的关系相关的知识,希望对你有一定的参考价值。

参考技术A 首先,要知道截量的定义:把截集中所有弧的容量之和成为截集的容量(即截量)。所以:任何一个可行流的流量v(f)都不会超过任一截集的容量。显然,如果对于一个可行流f^,网络D=(V,A,C)中有一个截集(V^1,V~1),使v(f^)=c(V^1,V~1),则f^必是最大流,而(V^1,V~1)必是D的所有截集中,容量最小的一个,即最小截集。 参考技术B 网络流问题
(1) 概念:
网络流问题是图论中一类常见的问题, 应用在许多包含流量的系统中,同时也是求解其他一些图论问题的基础, 如求解图的顶点的连通度和边连通度、匹配问题等。
(2) 网流问题分类:

网络最大流
流量有上下界网络的最大流和最小流
最小费用最大流
流量有上下界网络的最小费用最大流

6.1 网络最大流

6.1.1 基本概念

1. 网络流理论基础

最大流最小割定理构成网络流理论基础。该定理包含以下几个概念

网络最大流
增广路
残留网络
最小割
2. 容量网络和网络最大流

a. 容量网络(capacity network)
有向图 G ( V , E ) G(V,E) G(V,E)中, 指定了源点 V s V_s V
s

汇点 V t V_t V
t

,每一条边上都有一个权值 c ( u , v ) > 0 c(u,v)> 0 c(u,v)>0即弧的容量。

b. 弧的容量
容量网络G中任意一条弧上的权值。表示最大可以通过的流量。

c. 弧的流量(Flow Rate)
通过网络G中每条弧 < u , v > <u,v> <u,v>上的实际流量(流量), 记为 f ( u , v ) f(u,v) f(u,v)。

d. 网络流(Network Flow)
所有弧上流量的集合 f = f ( u , v ) f=\f(u,v)\ f=f(u,v) , 称为容量网络G的一个网络流。 如图6.2 (b)所示, u u u代表容量, v v v代表弧上当前流量。

[!info]
弧上流量小于弧的容量
源 V s V_s V
s

流出的流量等于流入汇点 V t V_t V
t

的流量
任意的中间顶点 V i V_i V
i

, 流入与流出的流量相等
e. 可行流
作为可行流需要满足,弧流量限制条件和平衡条件的流。对任何一个容量网络可行流总是存在的。
弧流量限制
0 ≤ f ( u , v ) ≤ c ( u , v ) 0\leq f(u,v) \leq c(u,v)
0≤f(u,v)≤c(u,v)

f ( u , v ) f(u,v) f(u,v) : 弧 ⟨ u , v ⟩ \braket u,v ⟨u,v⟩ 的流量
平衡条件
∑ v f ( u , v ) − ∑ v f ( v , u ) = ∣ f ∣ , 当 u = V s 0 , 当 u ≠ V s , V t − ∣ f ∣ , 当 u = V t \sum_vf(u,v) - \sum_vf(v,u) =
⎧⎩⎨⎪⎪|f|,0,−|f|,当u=Vs当u≠Vs,Vt当u=Vt

|
f
|
,

u
=
V
s
0,

u

V
s
,
V
t

|
f
|
,

u
=
V
t

v


f(u,v)−
v


f(v,u)=





∣f∣,
0,
−∣f∣,


当u=V
s


当u

=V
s

,V
t


当u=V
t




∑ v f ( u , v ) \sum_vf(u,v) ∑
v

f(u,v): 从顶点 u u u流出的流量总和
∑ v ( v , u ) \sum_v(v,u) ∑
v

(v,u) : 流入顶点 u u u的流量总和
f f f : 该可行流的流量,即源点的净流出流量,或汇点的净流入流量
f. 零流(Zero Flow)
网络图中,每条弧上的流量为0,该网络流被称为零流

g. 伪流(Pseudoflow) 或容量可行流
一个网络流只满足弧的容量限制条件,不满足平衡条件,这种网络流被称为伪流。或称为容量可行流。在预流推进算法中用到。

h. 最大流(Maximum Flow)
在容量网络 G ( V , E ) G(V,E) G(V,E)中,满足弧流量限制条件和平衡条件,且具有最大流量的可行流,称为网络最大流,简称最大流。

3. 链与增广路

容量网络G根据弧上流量和容量的关系,可以将分为4中类型

饱和弧 : f ( u , v ) = c ( u , v ) f(u,v) = c(u,v) f(u,v)=c(u,v)
非饱和弧 : f ( u , v ) < c ( u , v ) f(u,v) < c(u,v) f(u,v)<c(u,v)
零流弧: f ( u , v ) = 0 f(u,v) = 0 f(u,v)=0
非零流弧 : f ( u , v ) > 0 f(u,v) >0 f(u,v)>0
(1) 链

链: 容量网络图 G G G中的,源 u u u到汇 v v v的顶点序列,如: ( u , u 1 , u 2 , ⋯   , u n , v ) (u, u_1, u_2, \cdots, u_n, v) (u,u
1

,u
2

,⋯,u
n

,v) 。 要求相邻的两个顶点之间有一条弧,如 ⟨ u , u 1 ⟩ 或 ⟨ u 1 , u ⟩ \braket u,u1 或 \braketu1, u ⟨u,u1⟩或⟨u1,u⟩为容量网络的一条弧。
各弧分类:

前向弧(P+): 弧的方向与链的正方向一致的弧
后向弧(P-): 弧的方向与链的正方向相反的弧
链 P 1 = < V s , V 1 > , < V 1 , V 2 > , < V 2 , V 4 > , < V 4 , V t > P1=\<V_s, V_1>, <V_1, V_2>, <V_2, V_4>,<V_4, V_t>\ P1=<V
s

,V
1

>,<V
1

,V
2

>,<V
2

,V
4

>,<V
4

,V
t

>
前向弧: P 1 + = < V s , V 1 > , < V 1 , V 2 > , < V 2 , V 4 > , < V 4 , V t > P1+=\<V_s, V_1>,<V_1, V_2>, <V_2, V_4>,<V_4, V_t>\ P1+=<V
s

,V
1

>,<V
1

,V
2

>,<V
2

,V
4

>,<V
4

,V
t

>
后向弧: P 1 − = < V 2 , V 1 > P1-=\<V_2, V_1>\ P1−=<V
2

,V
1

>

同一条弧在不同的链中可能是前向弧也可能是后向弧
链 P 2 = < V s , V 2 > , < V 2 , V 1 > , < V 1 , V 3 > , < V 3 , V t > P2=\<V_s, V_2>, <V_2, V_1>, <V_1, V_3>,<V_3, V_t>\ P2=<V
s

,V
2

>,<V
2

,V
1

>,<V
1

,V
3

>,<V
3

,V
t

>
如弧 < v 2 , v 1 > <v_2,v_1> <v
2

,v
1

>在链P1中为后向弧,在链P2中为前向弧
(2) 增广路

概念

满足一下两个条件的链P,成为增广路(增广链,可改进路):

P+中每一条弧都是非饱和弧
链P上的所有前向弧 < u , v > <u, v> <u,v>上, 0 ≤ f ( u , v ) < c ( u , v ) 0\leq f(u, v) <c(u, v) 0≤f(u,v)<c(u,v)
P-中每一天弧都是非零流弧
链P上的所有后向弧 < u , v > <u, v> <u,v>上, 0 < f ( u , v ) ≤ c ( u , v ) 0<f(u,v)\leq c(u,v) 0<f(u,v)≤c(u,v)
成为增广路的原因

增广的规则

4. 残留容量和残留网络

在残留网络中,从源点到汇点的任意一条简单路径都对应一条增广路。
路径上每条弧容量的最小值即为能够一次增广的最大流量。

5. 割与最小割

6.1.2 最大流最小割定理

网络流是最大流的判定定理:
增广路定理:
设容量网络G(V, E)的一个可行流f, f为最大流的充要条件是在容量网络中不存在增广路。
最大流最小割定理:
对容量网络G(V, E), 其最大流的流量等于最小割的容量
以上定理推算出一下四个等价结论:
f是容量网络的最大流
|f|等于容量网络最小割的容量
容量网络中不存在增广路径
残留网络G’中不存在从源点到汇点的路径
6.1.3 网络最大流求解

求容量网路的最大流有两大类算法:增广路算法(Augmenting Path Algorithm)和预流推进算法(Preflow-push Algorithm)

1. 增广路算法

思路:
根据增广路定理,从任何一个可行流开始,沿着增广路对网络进行增广,直到网络不存在增广路为止。

关键:寻找增广路和改进网络流
如何有效的找到增广路,并保证算法在有限次增广后一定终止。

网络流求最大流算法

一、网络流的定义:有向图G=(V,E)中,点集中有一源点S,一汇点T。且S入度为0,T出度为0。对于每条边edge,都有一权值函数c,表示其容量,一权值函数f,表示其实际流量。

满足对于任意一条边都有f(edge)<=c(edge)。

二、最大流的定义:在不违背网络流的定义下,S到T的最大流量。

三、増广路的思想。

我们先考虑一个网络流:红色数字表示实际流量,蓝色表示边的容量,黄色表示更优的流量。

这个流从S到T的流量是5,但其显然不是最优的。

这个流比上面那个优,而且事实上,这个流就是当前网络的最大流。

我们将两个图比较,得出下图

我们发现因为这条路径上的每条边流量都加了一。注意到其中有一条A到B的反向边,所以我们寻找这种路径时,应把原图中所有边的剩余流量和已经流量的反向边加进去(退流),当图中不存在这种路径时,此图已成最大流。(顺便提一下,这种路径叫増广路径)。

四、求最大流的算法:

 FF:xyf大神说FF就是每次将源点的压力增加1,找一下増广路,慢点要死。于是直接上EK。

EK:每次找一条増广路,将这条路径上所有的流量增加(不管正向反向,其实这里已经没有流量这个概念了)找到增广路径中最小的△。

上代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
#define N 1100
#define INF 0x3F3F3F3F
struct note
{
    int to,cap,rev;    
};
vector<note> path[N];
bool used[N];
int n,m;
void make_way(int u,int v,int c)
{
    path[u].push_back((note){v,c,path[v].size()});
    path[v].push_back((note){u,0,path[u].size()-1});
}
int dfs(int s,int t,int f)
{
    if(s==t) return f;
    used[s]=1;
    for(int i=0;i<path[s].size();i++)
    {
        note &tmp=path[s][i];
        if(used[tmp.to]==false&&tmp.cap>0)
        {
            int d=dfs(tmp.to,t,min(f,tmp.cap));
            if(d>0)
            {
                tmp.cap-=d;
                path[tmp.to][tmp.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}
int max_flow(int s,int t)
{
    int flow=0;
    while(1)
    {
        memset(used,0,sizeof(used));
        int f=dfs(s,t,INF);
        if(f==0) return flow;
        flow+=f;
    }
}
int main()
{
    scanf("%d %d",&m,&n);
    for(int i=1;i<=m;i++)
    {
        int u,v,c;
        scanf("%d %d %d",&u,&v,&c);
        make_way(u,v,c);
    }
    printf("%d\\n",max_flow(1,n));
}

 dinic:就是先对图进行分层遍历,然后在分层图中进行dfs搜索,比EK快,10000的随即数据随便过。

 

以上是关于网络最大流量与载量容量的关系的主要内容,如果未能解决你的问题,请参考以下文章

网络最大流

网络流--最大流问题

网络流之最大流

网络流求最大流算法

网络最大流入门

网络流知识点汇总