网络最大流量与载量容量的关系
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的随即数据随便过。
以上是关于网络最大流量与载量容量的关系的主要内容,如果未能解决你的问题,请参考以下文章