PH N PH L C
Ph l c 2
Bài toán lu ng c c đ i
Cho m ng G=(V,E). Hãy tìm lu ng f* trong m ng v i giá tr lu ng val(f*)
l n nh t. Lu ng nh v y ta s g i là lu ng c c đ i trong m ng ư .
Bài toán nh v y có th xu t hi n trong r t nhi u ng d ng th c t . Ch ngư ế
h n khi c n xác đ nh c ng đ l n nh t c ang v n t i gi a hait c a m t b n ườ
đ giao thông. Trong thí d này l i gi i c a bài toán lu ng c c đ i s ch cho ta các
đo n đ ng xe đông nh t chúng t o thành ch h p t ng ng c a dòng giao ườ ươ
thông xét theo hai nút đã ch n. M t thí d khác là n u xét đ th t ng ng v i m t ế ươ
h th ng đ ng ng d n d u, trong đó các ng t ng ng v i các cung, đi m phát ườ ươ
có th coi là tàu ch d u, đi m thu là b ch a,n c đi m n i gi a c ng là các
t c a đ th , kh năng thông qua c a các cung t ng ng v i ti t di n các ng. ươ ế
C n ph i tìm lu ng d u l n nh t có th b m d u t tàu ch d u vào b ch a. ơ
Đ nh lý:c m nh đ d i đây là t ng đ ng: ướ ươ ươ
(i) f là lu ng c c đ i trong m ng.
(ii) Không tìm đ c đ ng tăng lu ng f.ượ ườ
(iii) Val(f)=c(X,X*) v i m t lát c t (X,X*) nào đó.
(Ta g i lát c t (X,X*) m t cách phân ho ch t p đ nh V c a m ng ra thành hai t p
X và X*=V\X, trong đó s
X và t
X*.)
Đ nh lý trên là c s đ xây d ng thu t toán l p sau đây đ tìm lu ng c c đ i ơ
trong m ng: B t đ u t lu ng trên t t c các cung b ng 0 (ta s g i lu ng nh v y ư
là lu ng không), và l p l i b c l p sau đây cho đ n khi thu đ c lu ng mà đ i v i ướ ế ượ
khôngn đ ng tăng:ườ
B c l p tăng lu ngướ (Ford Fulkerson): Tìm đ ng tăng P đ i v i lu ng hi n có,ườ
tăng lu ng d c theo đ ng P. ườ
Khi đã có lu ng c c đ i, lát c t h p nh tth m theo th t ct trong
vi c ch ng minh đ nh trên. Thu t toán Ford-Fulkerson đ c t trong th t c ượ
sau đây:
Procedure Luongcucdai;
Begin
Stop := false;
While not Stop do
If <m đ ng tăng lu ng P> then ườ
< Tăng lu ng d c theo P>
Else Stop := true;
End;
158
Đ tìm đ ng tăng lu ng trong G(f) có th s d ng thu t toán m ki m theo ư ế
chi u r ng (hay tìm ki m theo chi u sâu), b t đ u t đ nh s trong đó kng c n xây ế
d ng t ng minh đ th G(f). Ford-Fulkerson đ ngh thu t toán gán nhãn chi ti t sau ườ ế
đây đ gi i bài toán lu ng c c đ i trong m ng. Thu t toán b t đ u t lu ng ch p
nh n đ c nào đó trong m ng (có th b t đ u t lu ng không) , sau đó ta s tăng ượ
lu ng b ng cách m các đ ng tăng lu ng. Đ tìm đ ng tăng lu ng ta s áp d ng ườ ườ
ph ng pháp gán nhãn cho các đ nh. M i đ nh trong quá trình th c hi n thu t toán sươ
m t trong ba tr ng thái: ch a nhãn, nhãn ch a xét, nhãn đã xét. Nhãn c a ư ư
m t đ nh v g m hai ph n m t trong hai d ng sau : [
( )p v+
,
( )v
ε
] ho c [
( ), ( )p v v
ε
]. Ph n th nh t +p(v) (-p(v)) ch ra c n tăng gi m lu ng theo cung
(p(v),v)( cung (v,p(v)) n ph n th hai
( )v
ε
ch ra l ng l n nh t th tăng ho c ư
gi m lu ng theo cung này. Đ u tiên ch có đ nh s đ c kh i t o nhãn và nhãn c a nó ư
là ch a xét, còn t t c các đ nh còn l i đ u ch a có nhãn. T s ta gán nhãn cho t t cư ư
các đ nh k v i nó và nhãn c a đ nh s s tr thành đã xét. Ti p theo, t m t đ nh v có ế
nhãn ch a xét ta l i gán nhãn cho t t c các đ nh ch a có nhãn k v i nó và nhãn c aư ư
đ nh v tr thành đã xét. Quá tnh s đ c l p l i cho đ n khi ho c là đ nh t tr thành ượ ế
nhãn ho c nhãn c a t t c các đ nh nhãn đ u đã xét nh ng đ nh t v n ư
không nhãn. Trong tr ng h p th nh t ta tìm đ c đ ng tăng lu ng, còn trongườ ượ ườ
tr ng h p th hai đ i v i lu ng đang t không t n t i đ ng tăng lu ng (t c ườ ườ
lu ng đã c c đ i). M i khi tìm đ c đ ng tăng lu ng, ta l i tăng lu ng theo đ ng ượ ườ ườ
tìm đ c, sau đó xoá t t c các nhãn và đ i v i lu ng m i thu đ c l i s d ng phépượ ượ
n nhãn các đ nh đ tìm đ ng tăng lu ng. Thu t toán s k t thúc khi nào đ i v i ườ ế
lu ng đang có trong m ng không tìm đ c đ ng tăng lu ng. ượ ườ
Hai th t c tìm đ ng tăng lu ng th t nh sau : ườ ư
Procedure Find-path;
{
Th t c gán nhãn đ ng tăng lu ng ườ
p[v],
ε
[v] nhãn c a đ nh v;
VT là danh sáchc đ nh nhãn ch a xét ; ư
c[u,v] kh năng thông qua c a cung (u,v),u,v
V;
f[u,v]lu ng trên cung (u,v), (u,v
V);
}
BEGIN
p[s] := s ;
ε
[s] :=
+∞
;
VT := {s};
Pathfound := true;
While VT<> {} do
BEGIN
159
u
VT ;( * l y u t V T *)
For v
V do
If (v ch a có nhãn) thenư
Begin
If (c[u,v] >0) and (f[u,v] < c[u,v] ) then
Begin
P[v] := u ;
ε
[v] := min {
ε
[u],c[u,v]-f[u,v] };
VT:=VT
{v};(* n p vo danh sách các đ nh có nhãn *)
If v = t then exit;
End
Else
If (c[v,u] > 0) and (f[v,u] < 0) then
Begin
P[v] := u ;
ε
[v] := min {
ε
[u] , f[u,v] };
VT:=VT
{v};(* n p vo danh sách các đ nh có nhãn *)
If v = t then exit;
End;
End;
End;
160
PathFound :=false;
End;
Procedure Inc_flow ;
{ thu t toán tăng lu ng theo đ ng tăng } ườ
Begin
v := t ;
u := t ;
tang := [t];
while u <> s do
begin
v := p[u];
if v > 0 then f[v,u] := f[v,u] + tang
else
begin
v := -v;
f[u,v] :=f[u,v] –tang;
end;
u := v ;
end;
Procedure FF;
{ th t c th hi n thu t toán Ford_fulkerson }
Begin
(* kh i t o b t đ u t lu ng v i giá tr 0 *)
For u
V do
For v
V do f[u,v] :=0;
Stop := false;
While not Stop do
begin
find_path;
If pathfound then
Inc_flow
Else
Stop:=true;
End;
< Lu ng c c đ i trong m ng là f[u,v], u,v
V >
< Lát c t h p nh t là (V T , V\ VT) >
End;
161
Ch ng trình sau ch ng trình ph c v cho vi c h c t p và gi ng d y vươ ươ
i toán m lu ng c c đ i trong m ng. Ch ng trình sau đ c xây d ng b ng công ươ ượ
c l p trình Delphi.
Các ch c năng c a ch ng trình: ươ Ta xây d ng ch ng trình bao g m nh ng ch c ươ
năng sau:
* Tóm t t thu t toán Ford – Fulkeson.
* Hi n th c b c th c hi n ng v i t ng ví d c th . ướ
Tóm t t thu t toán Ford – Fulkerson :
Ch c năng y m c đích giúp cho ng i s d ng n m v ng đ c thu t ườ ượ
toán tr c khi đi vào các thí d c th . ướ
Hi n th các b c th c hi n c a bài toán: ướ
Do ch ng trìnhươ nh m m c đích ph c v cho vi c d y và h c môn Tn r i
r c nên ch c năng vi c hi n th chi ti t các b c gi i bài toán ng v i t ng thí d c ế ướ ư
th giúp cho ng i s d ng hi u rõ h n v thu t toán. ườ ơ
C u trúc d li u và cài đ t thu t toán:
C u trúc d li u:
Đ th đ c l u gi d i d ng t p đ nh và t p c nh. M i đ nh đ c l u theo ượ ư ướ ượ ư
c u trúc c a m t Record nh sau: ư
L_TypeDinh = record
Ten:String;
ToaDo:L_TypeToaDo;
MucKichHoat:Byte;
end;
Trong đó:
- Bi n Ten có ki u String , l u gi tên đ nh (m t đ nh là Vế ư 0,V1,…)
- Bi n ToaDo ki u L_TypeToaDo, l u gi to đ x, y c a m i đ nh cóế ư
c u trúc c a m t Record nh sau : ư
L_TypeToaDo = record
x,y:integer;
end;
Bi n Muckichhoat có ki u Byte l u gi m c đ kích ho t c a đ nh (m i đ nhế ư
4 m c kích ho t kc nhau), bi n này ng đ c đ nh đ nh đ u, đ nh cu i, đ nh ế
h p….
162