6. Bố cục của đề tài
2.4.4. Các thuật toán cải tiến
Ở các phần trên, chúng ta đã xét một số thuật toán giúp giải bài toán luồng với chi phí cực tiểu. Mặc dù các thuật toán này đảm bảo sự hội tụ nếu như dữ liệu trong bài là số nguyên, nhưng việc tính toán không được giới hạn bởi một hàm đa thức. Và như vậy, thuật toán không đảm bảo sẽ giải tốt tất cả các bài toán được đặt ra. Dưới đây là một số cải tiến quan trọng của các thuật toán trên để bài toán có thể giải trong thời gian đa thức.
2.4.4.1. Cải tiến thuật toán tìm đường đi ngắn nhất liên tiếp
Thuật toán tìm đường đi ngắn nhất liên tiếp có 2 thuật toán cải tiến nhằm tối ưu hóa thời gian chạy của thuật toán. Phương pháp thứ nhất là tác động lên yếu tố luồng trong đồ thị thặng dư, phương pháp thứ hai là tác động lên yếu tố chi phí, tương ứng ta
có các thuật toán tỷ lệ theo thông lượng (Capacity scaling) và tỷ lệ theo chi phí (Cost scaling). Sau đây chúng ta sẽ nghiên cứu thuật toán tỷ lệ theo thông lượng.
Thuật toán tỉ lệ theo thông lượng áp dụng cho bài toán luồng với chi phí cực tiểu bảo đảm rằng mỗi lần tăng trưởng đường đi ngắn nhất sẽ mang theo một lượng lớn luồng dọc theo đường đi này.
Thuật toán tỉ lệ theo thông lượng sử dụng một luồng giả x và giá trị ei, với ei là
giá trị mất cân bằng tại nút i được định nghĩa như sau:
( , ) ( , ) i i ji ij j i E j i E e b f f Với i N
Thuật toán duy trì một luồng giả thỏa mãn điều kiện giảm chi phí tối ưu và từng bước biến đổi luồng giả này thành một luồng bằng cách xác định đường đi ngắn nhất từ các nút thừa đến các nút thiếu và tăng luồng dọc theo các đường này.
Đặt một pha tỉ lệ có giá trị cụ thể là . Ban đầu, A = 2log|u|. Thuật toán bảo đảm
rằng trong mỗi pha tỉ lệ , mỗi lần tăng trưởng sẽ mang chính xác đơn vị luồng.
Khi không còn nút nào vượt quá giá trị tối thiểu hay không còn nút nào thấp hơn
giá trị tối thiểu thì thuật toán sẽ giảm giá trị đi 2 lần và tiếp tục tiến trình. Cuối
cùng khi = 1 thì pha này kết thúc và ta nhận được một luồng. Luồng này chính là
luồng tối ưu vì nó thỏa mãn điều kiện giảm chi phí tối ưu.
Với giá trị A, ta định nghĩa hai tập hợp S() và T() như sau:
S() = {i: e > A}
T() = {i: e < - A}
Trong một pha tỉ lệ, mỗi lần tăng trưởng phải bắt đầu từ một nút trong S() và
kết thúc tại một nút trong T(). Ngoài ra, sự tăng luồng phải diễn ra trên một đường
đi có cạnh có độ thông qua thặng dư tối thiểu là . Do đó, ta có một định nghĩa khác
như sau:
Mạng thặng dư G(f, ) là một mạng con của G(f), gồm những cạnh có độ thông
qua thặng dư tối thiểu là . Trong một pha tỉ lệ, thuật toán tăng một luồng từ một nút
trong S() đến một nút trong mạng G(f, ). Thuật toán đáp ứng tính chất mỗi cạnh
của G(f, ) thỏa mãn điều kiện giảm chi phí tối ưu. Tuy nhiên các cạnh của G(f) mà
không thuộc G(f, ) có thể vi phạm điều này. Cần chú ý thuật toán này chỉ tăng chính
xác A đơn vị luồng trong một pha tỉ lệ mặc dù nó có thể tăng nhiều hơn. Điều này thật sự hữu ích đối với các bài toán không ràng buộc về thông lượng luồng, khi đó các luồng trong mạng luôn là bội số nguyên của A.
Nhằm tạo nên tính đúng đắn của thuật toán ta cho rằng pha tỉ lệ 2 kết thúc khi
S(2) = 0 hoặc T(2) = 0. Khi đó, hoặc ei < 2 với i V hoặc ei > - 2 với
i V
. Điều kiện này cho thấy tổng giá trị vượt quá có thể đạt đến giá trị 2n.
Các bước thực hiện thuật toán:
begin
x: = 0 và : = 0;
= 2|logU|;
while A > 1 do begin
for each (i, j) trong mạng thặng dư G(f) if rij> và pij then
begin
Gửi rij đơn vị luồng dọc theo (i, j); Cập nhật f và ei; end; S() = {i: ei > }; T() = {i: ei < - }; while S(2A) ^ 0 và T(2) do begin Chọn nút k S() và nút l T(); Xác định khoảng cách ngắn nhất đi từ nút k đến các nút khác
trong mạng thặng dư G(f, ) và chi phí giảm pij ;
Gọi P là đường đi ngắn nhất từ nút k đến nút l trong G(f, );
Cập nhật Cập nhật : = - d;
Tăng A đơn vị luồng dọc theo P;
Cập nhật f, S(),T() và G(f, );
end;
:= /2;
end; end;
Thuật toán tỉ lệ theo thông lượng giải bài toán luồng với chi phí cực tiểu với độ phức tạp tính toán là O(mlogC S(n, m, nP));
2.4.4.2. Cải tiến thuật toán khử chu trình âm
Các thuật toán cải tiến chúng ta vừa xét là các thuật toán thời gian đa thức yếu vì thời gian chạy của nó dựa trên logC hoặc logP. Mặc dù những thuật toán này cho phép giải các bài toán có dữ liệu là số nguyên hoặc số hữu tỉ nhưng chúng không thích hợp đối với dữ liệu là số vô tỉ. Ngược lại những thuật toán thời gian đa thức mạnh có thời gian chạy dựa trên n hoặc m nên chúng thích hợp cho các bài toán có dữ liệu là số vô tỉ. Trong phần này, chúng ta xem xét một thuật toán thời gian đa thức mạnh, đó là thuật toán loại bỏ chu trình có giá trị trung bình nhỏ nhất (minimum mean cycle- canceling), đây là trường hợp đặc biệt của thuật toán khử chu trình âm.
Ta có chi phí trung bình của chu trình có hướng W là:
( . ) | W | ij i j W p
Thuật toán khử chu trình có giá trị trung bình nhỏ nhất bắt đầu với một luồng khả thi f. Tại mỗi lần lặp, thuật toán xác định một chu trình có giá trị trung bình nhỏ nhất W trong mạng. Nếu giá trị trung bình của W âm, thuật toán sẽ tăng một luồng lớn tối đa có thể và gửi qua chu trình W, cập nhật lại G(f) và lặp lại tiến trình. Nếu giá trị trung bình của W không âm ta có thể kết luận G(f) không chứa chu trình âm và f là luồng có chi phí nhỏ nhất và dừng thuật toán.
Ngoài ra thuật toán khử chu trình âm có một thuật toán cải tiến khác là thuật toán Cancel and tighten, đây là thuật toán được cải thiện từ thuật toán loại bỏ chu trình có giá trị trung bình nhỏ nhất bằng cách duy trì các nút tiềm năng để việc phát hiện chu trình âm dễ dàng và nhanh chóng hơn.
CHƯƠNG 3
XÂY DỰNG ỨNG DỤNG