Thuật toán Push-relabel

Một phần của tài liệu Tiểu luận Phân tích và thiết kế thuật toán LUỒNG CỰC ĐẠI (Trang 31)

Trong phần này, chúng tôi trình bày phương pháp “push-relabel" để tính “luồng cực đại”. Hiện nay, các thuật toán được phát triển dựa vào phương pháp “push- relabel" để tính luồng cực đại là nhanh nhất. Ngoài ra, những vấn đề của luồng như chi phí cực tiểu cũng có thể giải quyết một cách hiệu quả bằng các phương pháp “push-relabel". Trong phần này chúng tôi sẽ giới thiệu phương pháp tính luồng cực đại tổng quát của Goldberg với độ phức tạp là O(V2E), do đó hiệu quả hơn thuật toán của Edmond-Karp có độ phức tạp O(VE2).

Các thuật toán “push-relabel" làm việc một cách cục bộ hơn thuật toán Ford- Fulkerson. Thay vì phải kiểm tra toàn bộ mạng thặng dư G = (V, E) để tìm đường tăng luồng, phương pháp “push-relabel" chỉ làm việc trên một đỉnh tại một thời điểm nhằm tìm ra các đỉnh lân cận trong mạng thặng dư. Ngoài ra, khác với phương pháp Ford-Fulkerson, phương pháp “push-relabel" không duy trì thuộc tính chuyển luồng trong suốt quá trình thực thi mà sẽ thực hiện và duy trì một luồng trước (preflow) – là ánh xạ f : V × V → R thõa mãn tính chất đối xứng lệch, không vượt

quá khả năng thông qua và với mọi u ∈ V – {s} thì f(V, u) ≥ 0 . Chúng ta gọi tổng luồng tại mỗi đỉnh u là luồng vượt mức vào u được cho bởi: e(u) = f(V,u)

Với mọi đỉnh u ∈ V – {s, t} được gọi đỉnh quả tải nếu e(u) > 0

Chúng ta sẽ bắt đầu phần này bằng cách mô tả trực quan thuật toán push-relabel. Sau đó tìm hiểu hai thao tác là “đẩy” một luồng trước (preflow) và “gán lại nhãn”

cho một đỉnh. Cuối cùng ta biểu diễn thuật toán và phân tích tính đúng đắn và thời gian thực hiện của nó.

Mô tả trực quan

Chúng ta thực hiện phương pháp push-relabel với các dòng chất lỏng: giả sử một mạng vận tải G = (V,E) được biểu diễn bởi một hệ thống các đường ống thông nhau với các khả năng thông qua xác định. Thực hiện tương tự như phương pháp Ford-Fulkerson, chúng ta có thể nói rằng mỗi đường tăng luồng trong mạng cũng giống như thêm vào dòng chất lỏng mà không có các điểm nhánh với dòng chảy từ đỉnh phát tới đỉnh thu. Phương pháp Ford-Fulkerson thêm nhiều dòng chất lỏng cho đến khi không thể thêm được nữa.

Thuật toán push-relabel tổng quát có thể mô tả trực quan bằng nhiều cách khác nhau. Trước hết, các cạnh có hướng chính là các đường ống. Các đỉnh, là nơi giao nhau của các cạnh, có hai tính chất. Một là, để điều tiết luồng vượt mức, mỗi đỉnh có một ống thoát ra dẫn tới một bể chứa có dung tích tùy ý để có thể chứa chất lỏng. Hai là, mỗi đỉnh với sức chứa của nó và tất cả các ống kết nối với đỉnh đó nằm trên một mức có chiều cao tăng lên như trong các quá trình của giải thuật. Chiều cao của đỉnh xác định luồng được đẩy như thế nào: chúng ta chỉ đẩy luồng từ trên xuống, tức là từ một đỉnh cao đến đỉnh thấp hơn. Luồng từ một đỉnh thấp hơn đến một đỉnh cao hơn có thể được, nhưng ta chỉ thực hiện thao tác đẩy xuống. Chiều cao của đỉnh nguồn là |V|, và chiều cao của đỉnh thu là 0. Tất cả chiều cao của các đỉnh khác bắt đầu từ 0 và tăng theo thời gian. Đầu tiên, thuật toán gửi càng nhiều luồng càng tốt từ nguồn tới đỉnh thu. Tổng lượng gửi đi vừa đủ để lấp đầy dung tích các ống đi ra từ nguồn; tức là khả năng thông qua của các cung (s,V-s). Khi luồng đầu tiên chảy vào một đỉnh trung gian, nó sẽ gom lại trong bể chứa của đỉnh. Tại đây, cuối cùng nó đẩy xuống.

Tình huống cuối cùng có thể xảy ra là chỉ những ống xuất phát một đỉnh u và chưa bão hòa với luồng kết nối đến các đỉnh không cùng mức với đỉnh u hoặc được đẩy lên từ u. Trong trường hợp này, để giải tỏa đỉnh quá tải u khỏi luồng vượt mức của nó, chúng ta phải tăng chiều cao của nó - gọi là “gán lại nhãn” cho đỉnh u. Chiều cao của nó được tăng hơn một đơn vị so với chiều cao thấp nhất của các đỉnh lân cận có các ống ở trạng thái chưa bão hòa. Sau khi một định được gán lại nhãn, phải có tối thiểu một ống xuất phát từ nó với lưu lượng hơn có thể được đẩy.

Cuối cùng, tất cả các luồng có thể chuyển đến đỉnh thu. Không có một luồng nào khác có thể thể đến bởi vì các ống tuân theo ràng buộc khả năng thông qua; số lượng luồng băng qua bất kì lát cắt nào vẫn còn được giới hạn bởi khả năng thông qua của lát cắt. Để một luồng trước trở thành một luồng chấp nhận được thì thuật toán gửi luồng vượt mức được gom lại trong các bể chứa của đỉnh quá tải trở lại đỉnh phát bằng cách tiếp tục gán lại nhãn các đỉnh để đạt đến chiều cao |V| của

nguồn. Như chúng ta thấy, một khi tất cả các bể chứa đã được làm rỗng, thì luồng trước không chỉ là một luồng chấp nhận được, mà còn là luồng cực đại.

Các thao tác cơ bản

Từ phần mô tả trên, ta thấy có hai bước thực hiện cơ bản được thực hiện bởi thuật toán “push-relabel" :đẩy một luồng vượt mức từ một đỉnh tới một trong những lân cận của nó và gán lại nhãn cho một đỉnh. Sự hữu dụng của các bước này phụ thuộc vào khoảng cách của các đỉnh mà chúng ta có thể xác định chính xác.

Cho mạng vận tải G = (V, E) với đỉnh phát là s là đỉnh thu là t, và f là một luồng trước trong G. Một hàm chiều cao h : V → N được xác định bởi các tính chất sau: i. h(s) = |V|

ii. h(t) = 0

iii. h(u) ≤ h(v) + 1 với mọi cung thặng dư (u, v) ∈ Ef

Bổ đề 26.13

Cho mạng vận tải G = (V, E), gọi f là một preflow trong G, h là hàm chiều cao trên V. Với mỗi cặp đỉnh u,v ∈ V, nếu h(u) > h(v) + 1 thì (u,v) không phải là một cung trong đồ thị thặng dư.

Thao tác Push

Thao tác cơ bản PUSH(u,v) có thể thực hiện nếu u là một đỉnh quá tải cf(u,v) >0 và h(u) = h(v) + 1. Mã giả dưới đây cập nhật luồng trước f trong mạng G=(V,E). Giả sử khả năng thông qua còn dư có thể được tính trong thời gian không đổi được cho bởi c và f. Luồng vượt mức chứa tại đỉnh u được xác nhận như là thuộc tính e[u], và chiều cao của u được xác nhận như thuộc tính h[u]. Biểu thức df(u,v) là một biến tạm thời chứa một tập các luồng có thể được đẩy từ u đến v.

PUSH(u,v)

1 If ( u là đỉnh qua tải, cf(u, v) > 0 và h [u] = h [v] + 1)

2 Push df(u, v) = min(e[u], cf(u, v)) đơn vị luồng từ đỉnh u tới đỉnh v 3 df(u, v) := min(e[u], cf(u, v))

4 f [u, v] := f[u, v] + df(u, v) 5 f [v, u] := - f[u, v]

6 e [u] := e[u] - df(u, v) 7 e [v] := e[v] + df(u, v)

Giả sử đỉnh u có giá trị vượt mức là số dương, và khả năng thông qua còn dư của (u,v) cũng dương. Do dó, chúng ta có thể tăng luồng từ u đến v bởi df(u,v) = min(e[u], cf(u,v)) mà không làm e[u] mang giá trị âm hoặc không vượt quá khả năng thông qua c(u,v. Dòng 3 tính giá trị df(u,v), và chúng ta cập nhật f ở dòng 4-5 và e ở dòng 6-7. Do dó, nếu f là một preflow trước khi PUSH được gọi thì sau đó nó vẫn còn là một preflow.

Trong đoạn code trên ta thấy thủ tục PUSH chỉ được thực hiện khi thõa mãn điều kiện h[u] = h[v] + 1. Do đó mà luồng vượt mức được đẩy xuống chỉ bởi chiều cao chênh lệch 1 đơn vị. Bổ đề 26.13 cho thấy rằng không có cung dư nào tồn tại giữa hai đỉnh có chiều chênh lệch nhau lớn hơn 1 đơn vị. Và vì vậy mà nếu thuộc tính h thực sự là một hàm chiều cao thì không thu được một luồng nào bằng cách cho phép đẩy luồng xuống với độ chênh lệch chiều cao lớn hơn 1 đơn vị.

Bổ đề 26.14

Sau một quá trình đẩy không bão hòa từ đỉnh u tới đỉnh v thì đỉnh u không còn là đỉnh quá tải.

Chứng minh: Khi thực hiện một phép đẩy không bão hòa, dung lượng luồng df(u,v) thật sự được đẩy vào phải bằng e[u] trước khi đẩy. Khi e[u] được giảm bởi một lượng đó, nó sẽ bằng 0 sau khi đẩy. (adsbygoogle = window.adsbygoogle || []).push({});

Thao tác Relabel

Thao tác cơ bản RELABEL(u) được thực hiện nếu u là một đỉnh quá tải và nếu h[u] ≤ h[v] với mọi cung (u,v) ∈ Ef. Mặt khác, chúng ta có thể gán lại nhãn cho một đỉnh quá tải u nếu với mọi đỉnh v mà có khả năng thông qua từ u đến v còn dư, luồng không thể được đẩy từ u đến v vì v không thể đẩy xuống từ u. (Xem lại định nghĩa, hoặc đỉnh nguồn s hoặc đỉnh phát không thể quá tải, do đó đỉnh s và t không thể gán lại nhãn)

RELABEL(u)

1 If ( u là đỉnh quá tải và với mọi v ∈ V mà (u, v) ∈ Ef ta có h[u] ≤ h[v] ) 2 Tăng độ cao của u.

3 h[u] := 1 + min {h[v] : (u, v) ∈ Ef}

Khi gọi thao tác RELABEL(u), thì đỉnh u được gán lại nhãn. Chú ý rằng khi u được gán lại nhãn, Ef phải chứa ít nhất một cung xuất phát từ u, để giá trị nhỏ nhất trong đoạn code là một tập khác rỗng. Thuộc tính này xuất phát từ giả thiết rằng u là một đỉnh quá tải. Vì e[u] > 0, chúng ta có: e[u] = f(V,u) > 0 và do đó, phải có ít nhất một đỉnh v sao cho f[u,v] > 0

Nhưng khi đó:

cf(u,v) = c(u,v) – f[u,v] = c(u,v) + f[u,v]

> 0

Với (u,v) ∈ Ef

Thao tác RELABEL(u) gán cho u chiều cao lớn nhất có thể có bởi ràng buộc trong hàm chiều cao.

Thuật toán tổng quát

Thuật toán push-relabel tổng quát sử dụng chương trình con để tạo một luồng trước ban đầu trong mạng vận tải.

INITIALIZE-PREFLOW(G,s)

1 for mỗi đỉnh u ∈ V[G] 2 do h[u] := 0

3 e[u] := 0

4 for mỗi cung (u,v) ∈ E[G] 5 do f[u,v] := 0

6 f[v,u] := 0 7 h[s] := |V[G]|

8 for mỗi đỉnh u ∈ Adj[s] 9 do f[s,u] := c(s,u) 10 f[u,s] := -c(s,u) 11 e[u] := c(s,u) 12 e[s] := e[s] – c(s,u)

Chương trình con INITIALIZE-PREFLOW tạo một luồng trước ban đầu f định nghĩa bởi:

c(u,v) nếu u = s f[u,v] = - c(v,u) nếu v = s 0 nếu ngược lại

Mỗi cung rời đỉnh xuất phát s được lấp đầy khả năng thông qua, và tất cả các cung khác không có luồng. Với mọi đỉnh v lân cận đỉnh xuất phát, chúng ta có e[v] = c(s,v), và e[s] được khởi tạo là giá trị âm của tổng của những khả năng thông qua này. Thuật toán tổng quát cũng bắt đầu với việc khởi tạo hàm chiều cao h được xác định:

h[u] = |V| nếu u = s 0 nếu ngược lại 1

Đây là hàm chiều cao bởi vì chỉ những cung (u,v) thõa mãn h[u] > h[v] + 1 khi u = s, và các cung kia không bão hòa, điều đó có nghĩa là chúng không ở trong mạng thặng dư.

Sự thiết lập ban đầu được theo sau bởi một tuần tự các phép đẩy và gán lại nhãn, không được thực hiện trong một trật tự riêng biệt

Một phần của tài liệu Tiểu luận Phân tích và thiết kế thuật toán LUỒNG CỰC ĐẠI (Trang 31)