Thuật toán khử chu trình âm (Cycle canceling)

Một phần của tài liệu Bài toán luồng cực đại với chi phí cực tiểu và ứng dụng trong vận chuyển hàng cứu trợ bão lũ (Trang 32 - 37)

6. Bố cục của đề tài

2.4.1.Thuật toán khử chu trình âm (Cycle canceling)

2.4.1.1. Tư tưởng thuật toán

Điều kiện tối ưu về chu trình âm cho ta tiếp cận bài toán luồng với chi phí cực tiểu theo hướng đơn giản bằng cách tìm và khử chu trình âm trên đồ thị thặng dư cho tới khi đạt được điều kiện tối ưu là đồ thị không còn chu trình âm, gọi là thuật toán khử chu trình âm.

Tư tưởng của thuật toán: Thuật toán khử chu trình âm xuất phát từ một phương án khả thi và cải thiện hàm tối ưu của phương án đó.

2.4.1.2. Mô tả thuật toán

Xuất phát từ một luồng khả thi f trên đồ thị, ở mỗi một bước lặp ta tìm một chu trình có chi phí âm và tăng luồng trên chu trình này, khi đồ thị không còn chu trình âm thì bài toán kết thúc với một luồng tối ưu tìm được. Thuật toán khử chu trình âm có một kết quả phụ là định lý sau đây:

Định lý 2.4: Tính chất nguyên

Nếu tất cả các độ thông qua của cung và khả năng cung/cầu của các đỉnh là số nguyên thì bài toàn luồng với chi phí cực tiểu luôn có một luồng với chi phí nhỏ nhất là số nguyên.

2.4.1.3. Các bước thực hiện thuật toán

1. Tìm luồng cực đại ban đầu.

2. Điều kiện dừng: Nếu không có chu trình chi phí âm trong mạng thặng dư thì dừng. Luồng cực đại có chi phí cực tiểu.

3. Chọn chu trình chi phí âm trong mạng thặng dư. Tăng tối đa luồng trên chu trình âm.

Quay lại bước 2.

Giả code:

begin

Tìm một luồng khả thi x trong đồ thị;

while (đồ thị thặng dư G(f) chứa một chu trình âm) do

begin

Sử dụng một thuật toán để tìm một chu trình âm W;

 := min{rij:(i, j)  W};

Tăng  đơn vị luồng trong chu trình W;

Cập nhật G(f);

end; end;

Trong thuật toán tổng quát có hai công việc để mở, đó là tìm luồng cực đại ban đầu và tìm chu trình chi phí âm. Mỗi cài đặt cụ thể hai công việc này sẽ cho một thuật toán cụ thể.

Để tìm luồng cực đại ban đầu ta có thể sử dụng thuật toán bất kỳ thuộc nhóm đường đi tăng luồng. Để tìm chu trình chi phí âm ta có thể sử dụng thuật toán sau:

*Thuật toán Floyd-Warshall tìm chu trình âm

Đây là thuật giải tìm đường đi ngắn nhất giữa mọi cặp đỉnh trong đồ thị có hướng có trọng số. Tuy nhiên ta cũng có thể sử dụng thuật giải này tìm chu trình âm.

+ Đầu vào. Đồ thị G=(V,E), V= {1, 2, ... , n}, có trọng số w(i,j) với mọi cung (i,j).

+Đầu ra. Ma trận D=[d(i,j)].

Nếu trên đường chéo có trị âm d(k,k) < 0, thì tồn tại chu trình âm qua đỉnh k. Nếu trên đường chéo không có trị âm, thì d(i,j) là chiều dài đường đi ngắn nhất từ i đến j với mọi cặp (i,j).

Ma trận P=[p(i,j)] dùng để xác định chu trình âm hoặc đường đi ngắn nhất.

+Phương pháp. (adsbygoogle = window.adsbygoogle || []).push({});

(1) Bước khởi tạo: Ký hiệu D0 là ma trận xuất phát

D0 = [d0(i,j)]

trong đó d0(i,j) = w(i,j) nếu tồn tại cung (i,j) và d0(i,j) = + nếu không tồn tại

cung (i,j) (đặc biệt nếu không có khuyên tại i thì d0(i,i) = +).

P0 = [p0(i,j)]

trong đó p0(i,j) = j nếu có cung từ i đến j và p0(i,j) không xác định nếu không có cung từ i đến j.

Gán k:=0.

(2) Kiểm tra kết thúc:

Nếu k = n, kết thúc. D = Dn là ma trận độ dài đường đi ngắn nhất, P = Pn. Ngược lại tăng k lên 1 đơn vị (k:=k+1) và sang (3).

(3) Tính ma trận Dk và Pk theo Dk 1 và Pk 1:

Với mọi cặp (i,j), i=1, ..., n, j=1, ..., n, thực hiện:

Nếu dk 1(i,j) > dk 1(i,k) + dk 1(k,j) thì đặt

dk(i,j) := dk 1(i,k) + dk 1(k,j)

pk(i,j) := pk 1(i,k),

ngược lại đặt

pk(i,j) := pk -1(i,j) Quay lại bước (2).

-Phương pháp xác định chu trình âm qua đỉnh i : Giả sử d(i,i) < 0. Chu trình âm qua đỉnh i gồm dãy các đỉnh

i , i1 , i2 , i3 , ... , ik , ik+1 , ... , im , i thỏa mãn

i1 = p(i,i) , i2 = p(i1,i) , ... , ik+1 = p(ik,i) , ... , p(im,i) = i

Thuật toán Floyd-Warshall dễ cài đặt nhưng có độ phức tạp O(|V|3). Sau đây là

thuật toán Belmann-Ford tìm chu trình âm có độ phức tạp O(|V|.|E|).

*Thuật toán Bellman-Ford tìm chu trình âm

Thuật toán Bellman-Ford tìm đường đi ngắn nhất trong trọng đồ có trọng số âm, nếu không có chu trình âm. Nếu đồ thị có chu trình âm thì có thể xác định chu trình âm bằng thuật toán này.

+ Đầu vào. Đồ thị có hướng G=(V,E), V= {1, 2, ... , n}, có trọng số với mọi cung (i,j).

+Đầu ra. Chu trình âm, nếu tồn tại. +Phương pháp.

- Giai đoạn 1. Tìm thành phần liên thông mạnh (R.Kosaraju, 1980). Giai đoạn này có 2 bước.

(i) Duyệt đồ thị ngược của G theo chiều sâu. Gán nhãn thứ tự sau postord(v) cho

các đỉnh v  V. (adsbygoogle = window.adsbygoogle || []).push({});

(ii) Thực hiện duyệt đồ thị G theo thứ tự giảm dần của thứ tự sau postord(v).

for i:=1 to n do tplt[i]:=0; K:=0;

for postord(u) := n downto 1 do

if tplt[i] = 0 then

begin

K := K+1;

<xuất phát từ đỉnh u thực hiện thuật toán tìm cây phủ

end;

Kết luận: Các cây trong rừng tạo trong bước (ii) là các thành phần liên thông mạnh.

- Giai đoạn 2. Tìm chu trình âm trên các thành phần liên thông mạnh bằng phương pháp Bellman-Ford.

Hình 2.2. Minh họa thuật toán khử chu trình âm

Chúng ta dùng ví dụ trên hình vẽ 2-6(a) để minh họa thuật toán khử chu trình âm. (Chúng ta vi phạm giả thiết 4) để dễ khảo sát đồ thị hơn). Hình vẽ 2-6(a) mô tả một luồng khả thi trong đồ thị và hình vẽ 2-6(b) là đồ thị thặng dư tương ứng. Giả sử thuật toán chọn chu trình 4-2-3-4 có chi phí là -1 trước tiên. Khả năng thông qua thặng dư của chu trình này là 2. Thuật toán tăng 2 đơn vị luồng theo chu trình này. Hình vẽ 2-

a. Đồ thị có luồng khả thi f b. Đồ thị thặng dư G(f)

c. Đồ thị thặng dư sau khi tăng 2 đơn vị luồng theo chu trình 4-2-3-4

d. Đồ thị thặng dư sau khi tăng 1 đơn vị luồng theo chu trình 4-2-1-3-4

pij,cij pij,rij

fịj

6(c) vẽ đồ thị thặng dư bổ sung. Trong vòng lặp kế tiếp, giả sử thuật toán chọn chu trình 4-2-1-3-4 có chi phí -2. Thuật toán gửi 1 đơn vị luồng theo chu trình này. Hình vẽ 2-6(d) mô tả đồ thị thặng dư cập nhật. Vì đồ thị thặng dư không chứa chu trình âm nào nữa nên thuật toán kết thúc.

2.4.1.4. Độ phức tạp thuật toán

Trong bài toán luồng với chi phí cực tiểu, mPC là cận trên của chi phí luồng ban

đầu (vì pij < P và fij < C với ( , )i jE ) và -mPC là cận dưới của chi phí luồng tối

ưu (do pij> -P và fij < C với ( , )i jE). Mỗi vòng lặp của thuật toán khử chu trình

âm thay đổi giá trị hàm mục tiêu một lượng s là một giá trị âm.

Chúng ta giả sử tất cả dữ liệu của bài toán là số nguyên, thuật toán sẽ kết thúc

trong O(mPC) vòng lặp và chạy trong thời gian O(nm2PC).

Một phần của tài liệu Bài toán luồng cực đại với chi phí cực tiểu và ứng dụng trong vận chuyển hàng cứu trợ bão lũ (Trang 32 - 37)