- 在线时间
- 791 小时
- 最后登录
- 2022-11-28
- 注册时间
- 2017-6-12
- 听众数
- 15
- 收听数
- 0
- 能力
- 120 分
- 体力
- 36450 点
- 威望
- 11 点
- 阅读权限
- 255
- 积分
- 13896
- 相册
- 0
- 日志
- 0
- 记录
- 1
- 帖子
- 616
- 主题
- 542
- 精华
- 12
- 分享
- 0
- 好友
- 225
TA的每日心情 | 开心 2020-11-14 17:15 |
|---|
签到天数: 74 天 [LV.6]常住居民II
 群组: 2019美赛冲刺课程 群组: 站长地区赛培训 群组: 2019考研数学 桃子老师 群组: 2018教师培训(呼伦贝 群组: 2019考研数学 站长系列 |
1 最大流问题的数学描述
7 r% L: X8 |# C# X @' M1.1 网络中的流 定义' l9 Z+ M: w4 P& x, f1 q) d
在以V 为节点集, A 为弧集的有向图G = (V, A) 上定义如下的权函数:
" i3 c0 ^8 W( Y3 d0 e. v; a) m/ ?+ L4 K8 P) o. s: ? }& A
(i) L : A → R 为孤上的权函数,弧 (i, j)∈ A 对应的权 L(i, j) 记为 ,称为孤 (i, j) 的容量下界(lower bound); E- x9 [, A- J
1 M6 Z. U: j# u6 n. W- F* {(ii)U : A → R 为弧上的权函数,弧(i, j)∈ A对应的权U(i, j) 记为 ,称为孤 (i, j) 的容量上界或容量(capacity);. y, e+ z0 H* P$ s; Z- ]
, l m1 s( H* P4 C0 e4 h% l9 j(iii) D :V → R 为顶点上的权函数,节点i ∈V 对应的权 D(i) 记为 ,称为顶 点i 的供需量(supply/demand);$ x# {9 ]2 ? C% g
5 r1 R3 A4 k7 z* x {, A; w! q7 u4 F
此时所构成的网络称为流网络,可以记为 N = (V, A, L,U,D) 。 由于我们只讨论V, A 为有限集合的情况,所以对于弧上的权函数 L,U 和顶点上的 权函数 D ,可以直接用所有孤上对应的权和顶点上的权组成的有限维向量表示,因此 L,U, D 有时直接称为权向量,或简称权。由于给定有向图G = (V, A) 后,我们总是可 以在它的弧集合和顶点集合上定义各种权函数,所以流网络一般也直接简称为网络。) ~' Y0 ^/ o. v2 W1 g+ B, q' h1 D
1 B& d1 h6 H: _' k5 E
在流网络中,弧(i, j) 的容量下界 和容量上界表示的物理意义分别是:通过该 弧发送某种“物质”时,必须发送的最小数量为 ,而发送的最大数量为 。顶点i ∈V 对应的供需量则表示该顶点从网络外部获得的“物质”数量( > 0时),或从该顶 点发送到网络外部的“物质”数量(< 0 时)。下面我们给出严格定义。/ r2 t1 L/ k* m- L
4 f7 T0 T1 o- D+ C) A" f可行流(feasible flow)
0 D0 o# X3 m U1 p& U# }0 }7 y. B$ ~$ Y, A7 l
; a) P! u* }9 y4 F' g
# O6 r) Z7 T3 W9 _' B6 k& B' o
' U/ c* H' P# A: r' I( A$ r可见,当 di > 0时,表示有di 个单位的流量从网络外部流入该顶点,因此顶点i 称 为供应点(supply node)或源(source),有时也形象地称为起始点或发点等;当di < 0 时,表示有|di | 个单位的流量从该顶点流失到网络外部(或说被该顶点吸收),因此顶 点i 称为需求点(demand node)或汇(sink),有时也形象地称为终止点或收点等;当 di = 0时,顶点i 称为转运点(transshipment node)或平衡点、中间点等。此外,根据 (1)可知,对于可行网络,必有1 {. U9 l( P* ?9 |
6 I7 D" p4 F. G% w$ E+ i6 |- ~) @
![]()
" N0 C) u$ W# m5 C# u5 N$ N
/ }5 y. X8 y: J* E; |- B也就是说,所有节点上的供需量之和为 0 是网络中存在可行流的必要条件# O% k7 [) W$ Z8 \" W9 i
% [, }" w2 H6 e# g/ E8 l7 F. u6 H + o3 v: A, Z6 w# v% g
![]()
% F! d, @/ Z! f+ {( k( W
, M3 Y8 u8 N( k6 B3 x$ @1.2 最大流问题; |; h& c9 @, R. L7 v M' L7 A
考虑如下流网络 N = (V, A,U,D):节点 s 为网络中唯一的源点,t 为唯一的汇点, 而其它节点为转运点。如果网络中存在可行流 f ,此时称流 f 的流量(或流值,flow value)为 (根据(3),它自然也等于 − ),通常记为v 或v( f ) ,即$ `$ }. E& x, r0 b6 f
0 f5 t: o3 j3 H4 n3 w# P
4 d( }* p: k! h1 @5 V0 U( w
对这种单源单汇的网络,如果我们并不给定 和 (即流量不给定),则网络一 般记为 N = (s,t,V, A,U) 。最大流问题( maximum flow problem )就是在 N = (s,t,V, A,U) 中找到流值最大的可行流(即最大流)。我们将会看到,最大流问题 的许多算法也可以用来求解流量给定的网络中的可行流。也就是说,当我们解决了最大 流问题以后,对于在流量给定的网络中寻找可行流的问题,通常也就可以解决了。3 R2 }9 E9 K. ~3 H) ]4 m
! _( @8 b* w" Z0 M9 o& W3 r" I用线性规划描述最大流问题2 G1 r' c; Y; i0 g/ e: X, l
因此,用线性规划的方法,最大流问题可以形式地描述如下:( I9 s$ O" s" d* Q. s/ a& R
1 Q' a; I [* M : L5 S0 ~* y7 F2 |' i
7 ~/ ^/ q2 F1 C/ N/ ^9 y定义】 如果一个矩阵 A 的任何子方阵的行列式的值都等于0,1或 −1,则称 A 是 全幺模的(totally unimodular TU,又译为全单位模的),或称 A 是全幺模矩阵。
! J" X; a ?( ?2 d+ x( k( p# t0 G0 N1 W/ l
整流定理
$ I5 C) a, F3 X! ], ]- X% K1 P5 U【定理 7】(整流定理) 最大流问题所对应的约束矩阵是全幺模矩阵。若所有弧容量 均为正整数,则问题的最优解为整数解。 最大流问题是一个特殊的线性规划问题。我们将会看到利用图的特点,解决这个问 题的方法较之线性规划的一般方法要方便、直观得多。
2 `; b6 N* i+ p9 u, H' A' K% s5 q% b9 a6 Y4 j# n
1.3 单源和单汇运输网络9 T& g+ B- {! z& H7 d- B: F8 Y
多源多汇网络 转化成单源单汇网络
, I" b$ F: n4 y5 h2 u4 z0 Z- @实际问题往往是多源多汇网络,为了计算的规格化,可将多源多汇网络G 化成单 源单汇网络G' 。设 X 是G 的源,Y 是G 的汇,具体转化方法如下:
* C6 s' o* e: b) H- {( ?; a
, J' t, ~( d) N(i)在原图G 中增加两个新的顶点 x 和 y ,令为新图G' 中之单源和单汇,则G 中 所有顶点V 成为G' 之中间顶点集。
! N5 L; S/ e( E* n7 c6 y3 i( E! l, Q- F6 B6 h# e5 s/ p
(ii)用一条容量为∞的弧把 x 连接到 X 中的每个顶点。; G( ^1 h$ H! `( I
: Q: [# v0 c7 c. h4 g(iii)用一条容量为∞的弧把Y 中的每个顶点连接到 y 。 G 和G' 中的流以一个简单的方式相互对应。若 f 是G 中的流,则由9 O6 V, b" ?$ F9 m8 K2 [* I5 `
v; J1 r) j w
% t* I! f& c9 Y7 _
3 U0 N( ^- Q6 i+ x0 i/ y% E$ U" M
2 最大流和最小割关系割的容量 9 W* J, z* v5 y/ \
* H2 B% @# C1 h% s3 v# c9 K& R1 A( l
![]()
& w/ V$ v- K. M; i% H$ d4 g
H% ^5 U# n q* b则在这条可增广轨上每条前向弧的流都可以增加一个量δ ,而相应的后向弧的流可减 少δ ,这样就可使得网络的流量获得增加,同时可以使每条弧的流量不超过它的容量, 而且保持为正,也不影响其它弧的流量。总之,网络中 f 可增广轨的存在是有意义的, 因为这意味着 f 不是最大流。
$ {! D5 Z" T! j$ s3 K i& K' C
/ h' H1 X8 d. s! @ M; b9 N3 最大流的一种算法—标号法& I) Z' B1 a* H4 Y0 x8 ?% P4 {3 A$ G
标号法是由 Ford 和 Fulkerson 在 1957 年提出的。用标号法寻求网络中最大流的基 本思想是寻找可增广轨,使网络的流量得到增加,直到最大为止。即首先给出一个初始 流,这样的流是存在的,例如零流。如果存在关于它的可增广轨,那么调整该轨上每条 弧上的流量,就可以得到新的流。对于新的流,如果仍存在可增广轨,则用同样的方法 使流的值增大,继续这个过程,直到网络中不存在关于新得到流的可增广轨为止,则该 流就是所求的最大流。. b% O' `5 D; `7 \
3 |% P( U( ?$ Z3 a& ^这种方法分为以下两个过程:
2 Z: ]( s0 ~3 P
% W) z) y. ^( W( KA.标号过程:通过标号过程寻找一条可增广轨。8 G% L# G% E6 g: Q$ f( r
, {! C4 F- }: f8 `5 g9 o9 j
B.增流过程:沿着可增广轨增加网络的流量。
& {9 Z2 v1 w7 I1 |. |8 q5 ~" l/ k+ U S
这两个过程的步骤分述如下。
8 i% V- h+ |+ `# ?4 C! z( K6 ] E0 D6 L! i
(A)标号过程:! k; V' C* C5 C% M- r
7 M7 e5 O) H( r1 \' r! l![]()
' R* n$ t, h; k! I- E
/ S- e# H* L; e4 s" I(B)增流过程 + d% u6 G. L& |# R5 }2 D2 T
' t5 A/ i Q! \: ?7 a
网络最大流 x 的求解步骤5 i4 c9 ?$ y7 c9 h% G$ J& [
求网络 N = (s,t,V, A,U) 中的最大流 x 的算法的程序设计具体步骤如下:
8 d4 ^7 ]7 ]3 e$ E6 \; }: [/ `* P% w
1 w; e% T5 g6 F# t对每个节点 j ,其标号包括两部分信息 (pred( j),maxf(j))
$ w }, \3 a6 i2 G/ E; P. G0 T
; B% Z0 h) |' W$ ~5 ^/ X. i该节点在可能的增广路中的前一个节点 pred( j) ,以及沿该可能的增广路到该节点为止 可以增广的最大流量 maxf( j)。
# z$ K4 a- m5 B1 B- N
& Z( F( D; c1 F! K' T ) t1 e% s3 ]- T* i2 k
$ [7 B: k+ s0 K" x* G并将 j 加入 LIST 中。 例 17 用 Ford-Fulkerson 算法计算如图 6 网络中的最大流,每条弧上的两个数字分 别表示容量和当前流量。 ![]()
1 h. V r8 m+ v! f0 x' {- K3 ^3 z$ Y6 Y& P, T
3 c, L9 d' Y2 X P- \/ E$ B解 编写程序如下:; U D* s! c- q0 @0 ?' F8 y
; [- Y7 g, {8 E0 n' o( z. Z: Yclc,clear$ J; ~1 }, Z: x/ g/ |* ^6 L1 D
u(1,2)=1;u(1,3)=1;u(1,4)=2;u(2,3)=1;u(2,5)=2;
5 r+ g9 m; F( e% [; U) vu(3,5)=1;u(4,3)=3;u(4,5)=3;
1 f8 q5 f D5 m3 o- ?; S) tf(1,2)=1;f(1,3)=0;f(1,4)=1;f(2,3)=0;f(2,5)=1;
+ q! k( b0 r9 |: [9 Q6 }f(3,5)=1;f(4,3)=1;f(4,5)=0;* r8 k; h4 b T2 o! K
n=length(u);list=[];maxf(n)=1;$ z! e; N) R. I; v% m
while maxf(n)>0& o" \( M# ^5 B0 E3 o; S
maxf=zeros(1,n);pred=zeros(1,n);* e. p! f5 Q7 k0 Q+ Y! ]# G: s
list=1;record=list;maxf(1)=inf;% R) a! x0 M4 `! R
% list是未检查邻接点的标号点,record是已标号点, S( _; \% L0 P. G/ m( B1 R
while (~isempty(list))&(maxf(n)==0)
X1 \* g$ F! E, k/ A8 w flag=list(1);list(1)=[];6 e" W$ N+ A0 M I, W
label1= find(u(flag, -f(flag, );6 ~; ?/ q/ r# t: |. j6 q* \
label1=setdiff(label1,record);: O1 t9 |2 f# Y8 K
list=union(list,label1);
* P7 q& Z! I! n! d/ s' { pred(label1)=flag;
7 X/ G& v T" D2 C& |* X: D maxf(label1)=min(maxf(flag),u(flag,label1).... ^8 D% \2 y4 [! m
-f(flag,label1));8 h# S: W d* Z- L2 v
record=union(record,label1);
1 k0 T9 h, G! a* s+ e) k7 g label2=find(f(:,flag));" C. j! ^6 B6 d' m# F
label2=label2';! u- F0 S! {3 ~2 U; v. r
label2=setdiff(label2,record);
- J" X$ A+ f. ?* D$ n* t4 n1 a i list=union(list,label2);3 A) `/ ~/ W; }! m" X7 _/ E
pred(label2)=-flag;
2 P2 V# d# P' N! o4 E# R# E maxf(label2)=min(maxf(flag),f(label2,flag));
% ?% U( r: Q* a+ R% [+ H" J record=union(record,label2);
: r: u* d$ R$ Q6 o* a, Z1 ~ end/ C8 E8 x. K; m* O' W1 C* ~
if maxf(n)>0
# K* O6 q/ K' V1 g" T6 v; n; t v2=n; v1=pred(v2);
+ ^% a8 g& o* A* {) Z while v2~=1' | x0 Q& {; Y6 b
if v1>0- y9 e" c& _/ O* Z
f(v1,v2)=f(v1,v2)+maxf(n);6 A7 _8 W5 |) f3 f. y) F
else+ ]9 z+ x$ U$ L* J( y4 N8 z4 D
v1=abs(v1);
9 a: k" K$ v+ Q7 d# ` f(v2,v1)=f(v2,v1)-maxf(n);+ g- s- ~' t% D9 {# Z0 r
end
9 Z7 C1 o' t' \4 u$ L! N0 h v2=v1; v1=pred(v2);
% C/ ^7 y) @' O+ E/ _# H6 F end
$ l. I: ~+ f; B. e, [9 g end4 }; ~* V1 x. Q' F; v2 g
end
" I% q' c0 G7 r# g7 Zf % U- z9 q% r1 b: w; U
例18 现需要将城市 s 的石油通过管道运送到城市t ,中间有4个中转站 v1 ,v2 ,v3 和 v4 ,城市与中转站的连接以及管道的容量如图7所示,求从城市 s 到城市t 的最大流。
3 \8 ^- m2 r* C |1 I. W) a
0 ~" D* O4 s& M2 _9 F
" H! _( m3 t* M* H3 P/ n$ \![]()
5 j: h0 b# z2 y- J' S$ M$ D8 _0 d h) }$ X3 Y0 P
解 使用最大流的数学规划表达式,编写LINGO程序如下:
, b6 c% {, v% @6 m9 }2 R. g+ ~3 i/ `5 h( v3 N+ q
model:8 Q2 I5 U1 {" R
sets:
9 o2 g# h7 D+ }4 Unodes/s,1,2,3,4,t/;
+ e! g' h/ n7 k1 Uarcs(nodes,nodes)/s 1,s 3,1 2,1 3,2 3,2 t,3 4,4 2,4 t/:c,f;2 J" b8 f: i: |+ z4 v# s
endsets. q* y7 H% b9 Z. Y M7 B
data:6 j: k& Q% S; x% n# H; {$ T
c=8 7 9 5 2 5 9 6 10;4 [) x: M5 J! v9 }
enddata! g, n# u0 u& a/ k/ }. W
n=@size(nodes); !顶点的个数;
8 F$ e: o2 u) P. Q' rmax=flow;
( l! F+ \! [+ X@for(nodes(i)|i #ne#1 #and# i #ne# n:
F2 C Y& j* E8 z @sum(arcs(i,j):f(i,j))=@sum(arcs(j,i):f(j,i)8 a1 t M4 `8 w, m. \3 E
@sum(arcs(i,j)|i #eq# 1:f(i,j))=flow;
% |1 k4 [ O6 m@sum(arcs(i,j)|j #eq# n:f(i,j))=flow; ?2 [- a. L+ v1 @& A0 g$ y
@for(arcs bnd(0,f,c));' n. s6 L+ M* t1 | J1 s
end
# c- W& ]3 y# A, q5 ~1 g3 `6 Q' k# V5 F) ~9 B7 Y1 G$ B" S# P
在上面的程序中,采用了稀疏集的编写方法。下面介绍的程序编写方法是利用赋权邻 接矩阵,这样可以不使用稀疏集的编写方法,更便于推广到复杂网络。
" ^0 t2 s8 h" O' I6 O
, S! U A3 X7 y% y7 amodel:* y- O& @) n5 f2 Z
sets:2 [. _6 f5 A2 U; b4 _
nodes/s,1,2,3,4,t/;
: G7 G$ |- O7 S1 V, e; a8 Parcs(nodes,nodes):c,f;
2 p( J" o( F. U/ c* u5 qendsets$ r- h* S2 z8 X
data:
+ K, n. m; R( a2 yc=0;
- h7 g$ l4 F+ v! O6 q9 u8 T) y2 j@text('fdata.txt')=f;
5 t& c+ `1 F* |' g- y( E6 J6 Nenddata
/ j9 \& j7 h2 f. X3 E% A: Z) S/ a0 D8 gcalc:1 g$ r; ~3 m8 Z7 E3 d
c(1,2)=8;c(1,4)=7;
* Z. i; o% h9 G% Z$ M3 c/ qc(2,3)=9;c(2,4)=5;8 C0 i! n* |/ U" W
c(3,4)=2;c(3,6)=5;
- k6 ?8 E2 i0 r: W$ A- y2 n, u0 A" Hc(4,5)=9;c(5,3)=6;c(5,6)=10;' a/ d6 U6 @/ c) M) I, [3 u
endcalc
3 Q+ K Y/ z) X! O, g0 a# J5 j& @1 \n=@size(nodes); !顶点的个数;
4 S+ y- A0 s$ t4 U; H, l4 cmax=flow;2 b$ L; R; g$ R m
@for(nodes(i)|i #ne#1 #and# i #ne# n:6 j1 p {$ ?: A9 e
@sum(nodes(j):f(i,j))=@sum(nodes(j):f(j,i)));
& r! p3 f( i/ Y* W@sum(nodes(i):f(1,i))=flow;4 |$ b' ^7 s5 v+ ?
@sum(nodes(i):f(i,n))=flow;
* r; |* Y% p6 ?$ l- s@for(arcs bnd(0,f,c));
% Q! o0 l0 W1 W5 v7 ?: p, `4 Bend* B& A, {/ d( A2 n$ W, Z
; ^0 S4 ~+ m6 j$ g' n————————————————1 U c$ R6 X* W, O2 s
版权声明:本文为CSDN博主「wamg潇潇」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
# N0 v' c3 M5 Q) @/ ~& A) N0 Y原文链接:https://blog.csdn.net/qq_29831163/article/details/89786313
' p3 I( P" X8 B% ~% \9 X- e W. @8 S( d' B& q+ }
2 x/ C& w" b: x9 a, T- z |
zan
|