数学建模社区-数学中国

标题: 常用模型&算法总结—图&网络模型应用—树:连通性、最小生成树 [打印本页]

作者: 浅夏110    时间: 2020-5-21 09:56
标题: 常用模型&算法总结—图&网络模型应用—树:连通性、最小生成树
1 最大流问题的数学描述) u7 n2 i' i. Z( d$ b; X0 I2 \
1.1 网络中的流 定义% ^3 f% R  ?# b- B' P
在以V 为节点集, A 为弧集的有向图G = (V, A) 上定义如下的权函数:
5 Z* R9 v- u) T% x; J1 B; h8 L8 O7 L( W7 l6 c2 Q) o) U& j8 b
(i) L : A → R 为孤上的权函数,弧 (i, j)∈ A 对应的权 L(i, j) 记为 ,称为孤 (i, j) 的容量下界(lower bound);
$ v4 Q- F5 a/ D% u! N  U' P/ M$ k& S7 l# S
(ii)U : A → R 为弧上的权函数,弧(i, j)∈ A对应的权U(i, j) 记为 ,称为孤 (i, j) 的容量上界或容量(capacity);
# k+ o3 e" J; ^3 @% k  y% Q. ^- x+ \1 V3 }
(iii) D :V → R 为顶点上的权函数,节点i ∈V 对应的权 D(i) 记为  ,称为顶 点i 的供需量(supply/demand);$ z+ v$ i. C; y' l; ^

0 d  e0 R+ a$ _, O  W2 K此时所构成的网络称为流网络,可以记为 N = (V, A, L,U,D) 。 由于我们只讨论V, A 为有限集合的情况,所以对于弧上的权函数 L,U 和顶点上的 权函数 D ,可以直接用所有孤上对应的权和顶点上的权组成的有限维向量表示,因此 L,U, D 有时直接称为权向量,或简称权。由于给定有向图G = (V, A) 后,我们总是可 以在它的弧集合和顶点集合上定义各种权函数,所以流网络一般也直接简称为网络。9 m' y- v& |- a: K* a
2 R4 K8 l4 j8 _: F  m
在流网络中,弧(i, j) 的容量下界  和容量上界表示的物理意义分别是:通过该 弧发送某种“物质”时,必须发送的最小数量为 ,而发送的最大数量为 。顶点i ∈V 对应的供需量则表示该顶点从网络外部获得的“物质”数量( > 0时),或从该顶 点发送到网络外部的“物质”数量(< 0 时)。下面我们给出严格定义。1 j, ]3 c5 x; w7 G; \6 d% G
$ `7 w, B' ^8 E: @& h5 m
可行流(feasible flow)
$ U& S. b5 j* o7 ?1 O; q" ^1 e
" Q2 h! y* m0 T7 P  ^; v- Y7 _  n7 `! j4 }8 O) |& l
" H. X4 w' I6 P/ w5 l
! C& \3 p, x* G+ o
可见,当 di > 0时,表示有di 个单位的流量从网络外部流入该顶点,因此顶点i 称 为供应点(supply node)或源(source),有时也形象地称为起始点或发点等;当di < 0 时,表示有|di | 个单位的流量从该顶点流失到网络外部(或说被该顶点吸收),因此顶 点i 称为需求点(demand node)或汇(sink),有时也形象地称为终止点或收点等;当 di = 0时,顶点i 称为转运点(transshipment node)或平衡点、中间点等。此外,根据 (1)可知,对于可行网络,必有
  d% o% c  \6 c/ p) R  d
- l3 \; x7 o% |1 C4 R: l/ U( Q1 b8 [! Z
) p) N& ?" e: T9 g& Q+ y  _' b
也就是说,所有节点上的供需量之和为 0 是网络中存在可行流的必要条件
. `0 [4 I5 H' d( @: e8 [- ?4 V( Z% `" d+ u

. o" H% D+ Z) Z2 p" o
( E7 h+ c+ U' ?( O; _( Y8 Z# `5 B1 a/ [, c% Z2 M/ h
1.2 最大流问题+ D# y7 _* r* d* |2 q8 r' a& @  D- p% r
考虑如下流网络 N = (V, A,U,D):节点 s 为网络中唯一的源点,t 为唯一的汇点, 而其它节点为转运点。如果网络中存在可行流 f ,此时称流 f 的流量(或流值,flow value)为 (根据(3),它自然也等于 −  ),通常记为v 或v( f ) ,即/ r& f$ T: R5 m+ ]0 K) |1 J
3 d1 W+ w/ ~1 {; |# _
9 Q$ l. W/ ?" {
对这种单源单汇的网络,如果我们并不给定  和  (即流量不给定),则网络一 般记为 N = (s,t,V, A,U) 。最大流问题( maximum flow problem )就是在 N = (s,t,V, A,U) 中找到流值最大的可行流(即最大流)。我们将会看到,最大流问题 的许多算法也可以用来求解流量给定的网络中的可行流。也就是说,当我们解决了最大 流问题以后,对于在流量给定的网络中寻找可行流的问题,通常也就可以解决了。* O% l/ M# ?& t& O3 @
6 b, @6 L* e" |# }+ z( R; d
用线性规划描述最大流问题
% L1 g: ]: q# _+ H0 n% y; h因此,用线性规划的方法,最大流问题可以形式地描述如下:2 T/ ^( o8 J5 [, _6 j, C0 R
' M6 @( g* y8 L, h4 @1 {

6 }* b/ a' W+ l! j
% D9 f/ ?, _& V  ]5 R; i0 G定义】 如果一个矩阵 A 的任何子方阵的行列式的值都等于0,1或 −1,则称 A 是 全幺模的(totally unimodular TU,又译为全单位模的),或称 A 是全幺模矩阵。) r9 h* Y: {' m8 F$ E9 ?
( V" r9 x: Z" y( G" l& h
整流定理$ v! W! @9 I8 i  w% ]8 }4 D6 `
【定理 7】(整流定理) 最大流问题所对应的约束矩阵是全幺模矩阵。若所有弧容量 均为正整数,则问题的最优解为整数解。 最大流问题是一个特殊的线性规划问题。我们将会看到利用图的特点,解决这个问 题的方法较之线性规划的一般方法要方便、直观得多。& S$ j. l" O9 S% C- ~

, L6 Z& A' I) n0 D8 Z0 `9 p1 Z1.3 单源和单汇运输网络
; K$ U0 {4 H9 I1 K1 ~多源多汇网络 转化成单源单汇网络
6 `5 h# x- A) l& \+ C实际问题往往是多源多汇网络,为了计算的规格化,可将多源多汇网络G 化成单 源单汇网络G' 。设 X 是G 的源,Y 是G 的汇,具体转化方法如下:
% ?+ \) U, x- D! x; e+ s% u2 e, _( A! `( o0 O( ^4 M
(i)在原图G 中增加两个新的顶点 x 和 y ,令为新图G' 中之单源和单汇,则G 中 所有顶点V 成为G' 之中间顶点集。" v' A- B7 G1 t7 n8 D1 T2 p$ T. n

; r4 \' ~# M3 S! K# {6 }(ii)用一条容量为∞的弧把 x 连接到 X 中的每个顶点。% \7 Q! U6 W- \; H1 l1 \
6 ?0 i4 B) h4 k
(iii)用一条容量为∞的弧把Y 中的每个顶点连接到 y 。 G 和G' 中的流以一个简单的方式相互对应。若 f 是G 中的流,则由) N$ p$ ^* v. N% l  V5 {
; r1 |0 P( y' K* R" F+ p

, x0 y& |) G2 S* ~6 B9 G! M) }' E* R' `# w4 \) G( a
2 最大流和最小割关系割的容量5 D2 ]5 b1 \" m9 ~0 t( i

3 b% P( P* i, F- |! F5 e, o2 i* ^: F+ O& z0 ?) C

& W4 z: {6 S" Z# \则在这条可增广轨上每条前向弧的流都可以增加一个量δ ,而相应的后向弧的流可减 少δ ,这样就可使得网络的流量获得增加,同时可以使每条弧的流量不超过它的容量, 而且保持为正,也不影响其它弧的流量。总之,网络中 f 可增广轨的存在是有意义的, 因为这意味着 f 不是最大流。( e  }1 S7 n1 D3 r; n' N

) _; s2 R% M/ l9 w3 最大流的一种算法—标号法
/ Y3 e$ k' u5 p5 e+ G标号法是由 Ford 和 Fulkerson 在 1957 年提出的。用标号法寻求网络中最大流的基 本思想是寻找可增广轨,使网络的流量得到增加,直到最大为止。即首先给出一个初始 流,这样的流是存在的,例如零流。如果存在关于它的可增广轨,那么调整该轨上每条 弧上的流量,就可以得到新的流。对于新的流,如果仍存在可增广轨,则用同样的方法 使流的值增大,继续这个过程,直到网络中不存在关于新得到流的可增广轨为止,则该 流就是所求的最大流。* |/ ]) T1 q+ v& d8 Z% v1 u

6 P$ u9 U& ]. h# [7 z9 J/ x5 K; m+ R这种方法分为以下两个过程:, Q- L% r3 ^0 t; V

% E+ n! o1 ~9 B- L& @A.标号过程:通过标号过程寻找一条可增广轨。
. m5 n( L9 n' C# S7 P; N# c, [5 m4 D; |5 G$ x6 y5 O+ e4 `2 O& t( O7 m
B.增流过程:沿着可增广轨增加网络的流量。
! @* y% I% M) w/ g( g- w+ A0 @/ k! P
这两个过程的步骤分述如下。
$ W+ P* ]2 O' z' e5 [" \
; K) q  k3 n- A5 Q(A)标号过程:0 e, ]4 T- M4 e; g- q% C/ K8 O2 ?6 x
7 C7 I. U2 S6 T
2 A/ j( v! @+ z7 r$ L% Z

  [1 z- f2 \7 K) T4 e(B)增流过程$ V& T, {! y* S5 I4 t" I' U' U7 a

& G/ [3 i. ]3 g0 H1 V网络最大流 x 的求解步骤
5 \% I: d) _) r5 w/ w- ^$ {求网络 N = (s,t,V, A,U) 中的最大流 x 的算法的程序设计具体步骤如下:
0 p/ D, f; g1 n! M/ c+ O+ h# @9 ?/ d* t( }, q6 f/ r8 j; X+ U
对每个节点 j ,其标号包括两部分信息 (pred( j),maxf(j))
4 l8 g( A7 `+ ~2 T1 N; o
, {( g  i/ ?% j  M4 I该节点在可能的增广路中的前一个节点 pred( j) ,以及沿该可能的增广路到该节点为止 可以增广的最大流量 maxf( j)。
/ _5 E$ b  D+ f( W3 V1 f3 N+ p  B1 i9 e+ o! W4 @

7 W5 \1 @% y& F+ L& U6 U. L2 [( N# g) x" V% v; ^7 d

并将 j 加入 LIST 中。

例 17 用 Ford-Fulkerson 算法计算如图 6 网络中的最大流,每条弧上的两个数字分 别表示容量和当前流量。

6 P* y2 B. G2 x8 t$ f( W: `

& v, }+ V! _" [: A9 h* X9 e
! h/ i) Q/ e4 a  t解 编写程序如下:1 m& z) {7 q, p$ q4 g' U

, s+ e7 L+ h- v2 Q3 lclc,clear
1 P& @+ p5 X9 i; ^2 C  S* [1 E5 Su(1,2)=1;u(1,3)=1;u(1,4)=2;u(2,3)=1;u(2,5)=2;
; V# i. P8 _8 R+ w  P9 ku(3,5)=1;u(4,3)=3;u(4,5)=3;' k- t8 m) S* @+ h" s( A" B
f(1,2)=1;f(1,3)=0;f(1,4)=1;f(2,3)=0;f(2,5)=1;: @+ H; \1 T/ g( |% ]
f(3,5)=1;f(4,3)=1;f(4,5)=0;0 s' E  }0 b; d+ P
n=length(u);list=[];maxf(n)=1;, @# n4 X* B+ \
while maxf(n)>0
& J( t7 r% s5 p  L' K0 s/ Lmaxf=zeros(1,n);pred=zeros(1,n);# B  ^+ z- M: \' L9 T7 E
list=1;record=list;maxf(1)=inf;
' m9 z+ U. q9 C3 Y' C* |" T % list是未检查邻接点的标号点,record是已标号点
7 j6 q( S0 q0 q1 b" O4 Ewhile (~isempty(list))&(maxf(n)==0)# p/ }! y8 Y/ s! a
    flag=list(1);list(1)=[];; R  M* _* A; P7 n  n+ N' i. Q0 t
    label1= find(u(flag,-f(flag,);; G" M4 c  H$ w
    label1=setdiff(label1,record);3 ^3 A- R8 j$ T2 g( a( C
    list=union(list,label1);2 o/ C# a2 P# v! Q1 y7 ]3 d  E
    pred(label1)=flag;
1 o7 C$ n* v' |: t6 U; p% q" V    maxf(label1)=min(maxf(flag),u(flag,label1)...8 X# i# x+ M& o! K
    -f(flag,label1));  g% J5 d: \2 k: [# N) \
    record=union(record,label1);
. h. v5 G3 z7 o6 ?    label2=find(f(:,flag));0 s1 W! U: I* c7 N0 r
    label2=label2';8 o1 v  l6 k; T) d7 h
    label2=setdiff(label2,record);
- r' b0 l7 y1 S1 H    list=union(list,label2);$ @0 e$ `, i. X: X
    pred(label2)=-flag;
# t$ U; j6 r# Y) L8 _1 a" I    maxf(label2)=min(maxf(flag),f(label2,flag));
, T8 s! M5 r# l  y. ?! E2 R: b    record=union(record,label2);
& H* j0 ^* ~: Q9 H7 f" g end
. s5 `! v( A- b! l     if maxf(n)>0
2 s  N) N' w8 Q: O7 \* f! h        v2=n; v1=pred(v2);
! C: i3 ], y9 j2 r$ [8 v5 H9 r  F! y        while v2~=1
, z/ I* X1 O0 B! v- I. q# |, d            if v1>0* n" K  R$ N; Y. n
                f(v1,v2)=f(v1,v2)+maxf(n);
+ ^9 `) q2 x' m; R3 Q4 b            else2 u! E/ h" L6 s; w) ~3 v8 w4 Q
                v1=abs(v1);
# A* \- h/ h" h0 \5 [' |. U" h                f(v2,v1)=f(v2,v1)-maxf(n);
- T" Y" ]* ?7 w4 e& M% r1 V            end
9 l* u6 j6 w0 W; Y3 V* _1 r) F0 |9 v- W            v2=v1; v1=pred(v2);
- [  z2 F! M& b% ~3 S; M' B2 O        end
% [0 K. @" Z$ K  X    end9 y: J, z' J7 o* j- C
end3 {6 m0 W, ]  z" r. E( C
f 9 c( F, v% c$ g1 t# @
例18 现需要将城市 s 的石油通过管道运送到城市t ,中间有4个中转站  v1 ,v2 ,v3 和  v4 ,城市与中转站的连接以及管道的容量如图7所示,求从城市 s 到城市t 的最大流。
# D8 z1 j" n7 s' }# [* d8 E( `+ _# D7 I$ V, T1 J$ W
1 a" m, u/ I1 f% Y6 a
0 o4 ]5 q  g' p; V8 j
; }1 o3 W/ @* X0 v
解 使用最大流的数学规划表达式,编写LINGO程序如下:
; Z( S3 {2 U) @6 C3 K' t" T% f! ]# |* S0 r" b7 F
model:
! u4 G( Q1 J, y0 U) Ssets:0 m% t5 z& d( k+ E7 m4 K3 [
nodes/s,1,2,3,4,t/;. O+ q5 I. @3 W1 B6 l9 {
arcs(nodes,nodes)/s 1,s 3,1 2,1 3,2 3,2 t,3 4,4 2,4 t/:c,f;
. o0 m* e2 [& p- tendsets: s* D1 `1 W' ^5 B! e* E
data:8 t4 k2 R& J3 F  L2 G1 Q$ t
c=8 7 9 5 2 5 9 6 10;5 w  [2 g/ `3 s9 c
enddata% H% Q& T- ~2 k; t2 \, F9 Q
n=@size(nodes); !顶点的个数;
5 {0 z; m0 r3 g5 g% cmax=flow;" Z4 Q# e  v7 m* X1 H! W6 P- y
@for(nodes(i)|i #ne#1 #and# i #ne# n:
* r1 Y4 O5 d" L    @sum(arcs(i,j):f(i,j))=@sum(arcs(j,i):f(j,i)( v" U1 P( P2 F/ L
@sum(arcs(i,j)|i #eq# 1:f(i,j))=flow;& B# x  k9 {' C
@sum(arcs(i,j)|j #eq# n:f(i,j))=flow;
% N$ w' P2 Z) ^( i@for(arcsbnd(0,f,c));
$ l  _! r+ Z- J( Z+ @end 1 Z0 t3 }$ d9 M3 T' z

# h4 W2 }2 X; ^7 M6 f" [  z在上面的程序中,采用了稀疏集的编写方法。下面介绍的程序编写方法是利用赋权邻 接矩阵,这样可以不使用稀疏集的编写方法,更便于推广到复杂网络。: x: {: b6 P9 k. T2 X% e3 q

! v0 ]( E' b4 L7 D3 h# J% [; Imodel:: S6 {6 e* y/ Y7 p/ `
sets:4 B  y( o3 f* ]; m  k: A7 q# ?
nodes/s,1,2,3,4,t/;) }. d+ x1 l1 Y# k
arcs(nodes,nodes):c,f;
% m* J' ]- z" s: f3 w6 iendsets: m1 X( u/ o0 T3 _4 `) H4 \, Z
data:
3 h2 v+ X. d1 L8 oc=0;: S( e" K, d6 i: G* ~3 m8 C
@text('fdata.txt')=f;3 c; A. b! N4 J) U; [& g
enddata
: v8 ]2 B7 ?+ w# ecalc:
) w# d0 d: B/ dc(1,2)=8;c(1,4)=7;. j; ^' ^1 c& Z' M2 l* u7 @! k
c(2,3)=9;c(2,4)=5;. w! ~+ e% c' [
c(3,4)=2;c(3,6)=5;
* j' D5 B- K5 z6 X& b6 ^c(4,5)=9;c(5,3)=6;c(5,6)=10;
3 R' y" k6 W+ j$ n. bendcalc
9 @/ m( L& U5 \, Y" jn=@size(nodes); !顶点的个数;
4 W8 D" _5 J$ L: d" {/ Emax=flow;
3 \! n4 l3 {0 l2 N" G; N; h) h1 Z. n@for(nodes(i)|i #ne#1 #and# i #ne# n:
/ y/ T* Q# {) U$ \1 k& q    @sum(nodes(j):f(i,j))=@sum(nodes(j):f(j,i)));& r& T( ?# ~( d' k( O) R
@sum(nodes(i):f(1,i))=flow;
7 H& I+ O: r) Y' A" v  u: k: Q* G@sum(nodes(i):f(i,n))=flow;
  n; j6 D. l% h& v$ R3 r@for(arcsbnd(0,f,c));5 \  \: v: k; ?% V/ A! Q
end
! a; h' _1 |( \* y% E: k
' p7 o8 O0 x2 n1 `) v————————————————  c& ?+ @+ x" w" q, z  E) S4 e
版权声明:本文为CSDN博主「wamg潇潇」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
' y5 D' F' B" z0 z* S9 m8 x- R原文链接:https://blog.csdn.net/qq_29831163/article/details/89786313
7 X, L- W7 {5 Q+ I
$ j& q! o. `6 S: M( H- w0 e6 e. J; q6 U3 F: `. l





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5