Bài toán tối ưu rời rạc và Lượng cực đại
Trang 1ứng dụng luồng cực đại trong bài toán tối ưu rời rạc
Đức Trọng
I Bài toán
Xétbài toán:
i = 1,2,…,m;
j = 1,2,…,n
Bài toán trên là mô hình toán học của nhiều bàitoán tối ưu tổ hợp trong thực tế Ví dụ:
II Vídụ
1 Bài toán phânnhóm sinh hoạt:
Cóm sinh viên và n nhóm sinh hoạt chuyên đề.Với mỗi sinh viên i biết:
i=1,2,…,m; j=1,2,…,n
Trong số các cách phân các sinh viên vào nhóm chuyênđề mà họ có nguyện vọng tham
người trong nhómcó nhiều sinh viên tham gia nhất là nhỏ nhất có thể được
Đưa vào các biến số:
i=1,2, ,m ; j=1, 2, ,n, khi đó dễ thấy mô hình toán học cho bài toánđặt ra chính là bài toán (1)-(2)
2 Bài toán lậplịch cho hội nghị:
Mộthội nghị có m tiểu ban, mỗi tiểu ban cần sinh hoạt trong một ngày tạiphòng họp phù
hợp với nó Có n phòng họp dành cho việc sinh hoạt củacác tiểu ban Biết:
i=1,2, ,m, j=1, 2, ,n Hãy bố trí các phòng họp cho các tiểu bansao cho hội nghị kết thúc sau ít ngày làm việc nhất
Đưa vào các biến số :
Trang 2xij = 0, nếu ngược lại
i=1, 2, ,m ; j=1, 2, ,n, khi đó dễ thấy mô hình toán học cho bài toánđặt ra chính là bài toán (1)-(2), trong đó pi =1, i=1, 2, ,m
III Cơ sở thuật toán
Bổ đề 1:
Bài toán (1)-(2) có nghiệm tối ưu khi và chỉ khi:
Chứng minh:
Điều kiện cần là hiển nhiên vì sự tồn tại phương án của bàitoán suy ra bất đẳng thức
trong (3) được thực hiện ít nhất dưới dạng dấu đẳngthức
Điều kiện đủ: Chỉ cần chỉ ra rằng nếu có (3) thì luôn có phươngán
Giả sử (3) đúng, gọi:
Do(3) là điều kiện để (1)-(2) có nghiệm nên trong phần tiếp theo ta luôngiả thiết rằng điều kiệnđược thực hiên
Bâygiờ ta chỉ ra rằng bài toán (1)-(2) có thể chuyển về giải một số hữuhạn bài toán luồng
e thuộc E:khả năng thông qua c(e)
c(s,ui) = pi
c(ui,vj) = aij
c(vj,t) = k
Bổđề 2: Giả sử vớik nào đó luồng cực đại trong mạng G(k) có giá trị Δ thì x* với x*ij = Φ
Chứngminh: Thật vậy, do luồng cực đại trong mạng có giá trị Δ và là nguyên nên Φ (s,ui)
Vậy x* là phương án của bài toán (1)-(2) (đpcm)
Bổđề 3:
Trang 3Giả sử x*là phương án tối ưu và k* là giá trị tối ưu của bài toán(1)-(2) thì luồng cực đại
Chứng minh: Do giá trị của luồng cực đại trong mạng G(k*)không vượt qu Δ, nên để
Ta xây dựng luồng Φ như sau:
Bổđề 4:
Chứng minh:
Thậtvậy, giả sử x* là nghiệm bài toán (1)-(2) được xây dựngtheo công thức như bổ đề 1, xây dựng Φ theo bổ đề 3 ta có luồng giá trị Δ.(đpcm)
IV Thuậttoán:
Từ nhận xét 2 và 3 suy ra việc giải bài toán (1)-(2) là tìm k*nguyên dương nhỏ nhất sao
Từ đây rút ra thuật toán: áp dụng phương pháp chia nhị phântrên đoạn [1,m] tìm k* trong
mỗi bước giải bài toán tìm luồngcực đại trong
V Chương trình
Input: file văn bảnINPUT.TXT
- Dòng 1: Chứa 2 sốm,n (m,n ≤ 100)
- Trong m dòng tiếptheo mô tả mảng a
Output: file văn bản OUTPUT.TXT
- Dòng 1 chứa giátrị tối ưu tìm được
- Các dòng sau mô tả mảng x
Trang 4Chươngtrình:
UsesCrt;
Const
InputFile=’Input.Txt’;
OutputFile=’Output.Txt’;
Var
a,x:Array[1 100,1 100]of Integer; TraceX,TraceY:Array[1 100]of Integer; p:Array[1 100]of Integer;
Start,Finish,n,m,s,t,Delta,No:Integer; fi,fo:Text;
ProcedureInput;
Vari,j:Integer;
Begin
Assign(fi,InputFile);
Reset(fi);
Readln(fi,m,n);
Delta:=0;
For i:=1 to m do begin
read(fi,p[i]);
Delta:=Delta+p[i];
End;
For i:=1 to m do
For j:=1 to n do read(fi,a[i,j]);
Close(fi);
s:=m+1;t:=n+1;
For i:=1 to m do a[s,i]:=p[i];
End;
FunctionFindPath:Boolean;
Var
Trang 5Queue:Array[1 100]of Integer;
i,j,First,Last,v:Integer;
Begin
Fillchar(TraceX,Sizeof(TraceX),0); Fillchar(TraceY,Sizeof(TraceY),0); First:=1;Last:=0;
For i:=1 to m do
If x[s,i]
inc(last);
Queue[last]:=i;
traceX[i]:=-1;
end;
While First<=Last do Begin
i:=Queue[First];Inc(first);
For j:=1 to n do
If (traceY[j]=0)and(x[i,j]
traceY[j]:=i;
If x[j,t]
Finish:=j;
FindPath:=True;
Exit;
end;
For v:=1 to m do
if (TraceX[v]=0)and(x[v,j]>0) then begin Inc(Last);
Queue[Last]:=v;
TraceX[v]:=j;
end;
end;
End;
FindPath:=False;
End;
FunctionMin(x,y:Integer):Integer;
Begin
If x
End;
ProcedureIncFlow;
VarIncValue,i,j:Integer;
Begin
IncValue:=a[finish,t]-x[Finish,t];
j:=Finish;
While j>0 do begin
i:=TraceY[j];
IncValue:=Min(IncValue,a[i,j]-x[i,j]);
Trang 6j:=TraceX[i];
If j>0 then IncValue:=Min(IncValue,x[i,j]); End;
Start:=i;
IncValue:=Min(IncValue,a[s,start]-x[s,start]); j:=Finish;
While j>0 do begin
i:=TraceY[j];
x[i,j]:=x[i,j]+IncValue;
j:=TraceX[i];
If j>0 then x[i,j]:=x[i,j]-IncValue;
End;
x[s,start]:=x[s,start]+IncValue;
x[finish,t]:=x[finish,t]+IncValue;
End;
FunctionMaxFlow(k:Integer):Integer;
Vari,mf:Integer;
Begin
Fillchar(x,Sizeof(x),0);
For i:=1 to n do a[i,t]:=k;
Repeat
If not FindPath then break;
IncFlow;
Until False;
mf:=0;
For i:=1 to m do mf:=mf+x[s,i];
MaxFlow:=mf;
End;
ProcedureProcess;
varl,r,k:Integer;
Begin
l:=0;r:=m;
While l
k:=(l+r)div 2;
If MaxFlow(k)=Delta then r:=k
else l:=k+1;
End;
No:=r;
r:=MaxFlow(No);
End;
ProcedureOutput;
Vari,j:Integer;
Begin
Trang 7Assign(fo,OutputFile);
Rewrite(fo);
writeln(fo,No);
For i:=1 to m do begin
For j:=1 to n do write(fo,x[i,j],’ ’);
writeln(fo);
end;
Close(fo);
End;
BEGIN
Input;
Process;
Output;
END
VI.Độ phức tạp tính toán
Bài toán (1)-(2) giải được nhờ thuật toán đa thức có độ phứctạp tính toán là
O(log 2 m.OFN) trong đó OFN là độ phức tạptính toán tìm luồng cực đại