Thuật toán Dinitz

Thuật toán Dinitz là một thuật toán thời gian đa thức mạnh cho việc tìm luồng cực đại trên đồ thị luồng, tìm ra năm 1970 bởi nhà nghiên cứu khoa học máy tính người Israel (trước đó ở Liên Xô) Yefim Dinitz.[1] Thuật toán chạy trong thời gian O ( V 2 E ) {\displaystyle O(V^{2}E)} và tương tự như thuật toán Edmonds–Karp, chạy trong thời gian O ( V E 2 ) {\displaystyle O(VE^{2})} , ở chỗ nó cũng dùng đường tăng luồng ngắn nhất (ít cung nhất). Việc sử dụng các khái niệm đồ thị tầngluồng ngăn chặn cho phép thuật toán Dinitz đạt được thời gian nhanh hơn.

Định nghĩa

Giả sử G = ( ( V , E ) , c , s , t ) {\displaystyle G=((V,E),c,s,t)} là một mạng lưới với khả năng thông qua c ( u , v ) {\displaystyle c(u,v)} và luồng f ( u , v ) {\displaystyle f(u,v)} trên cung ( u , v ) {\displaystyle (u,v)} .

Khả năng thông qua còn dư là một ánh xạ c f : V × V R + {\displaystyle c_{f}:V\times V\to R^{+}} định nghĩa như sau,
  1. nếu ( u , v ) E {\displaystyle (u,v)\in E} , thì
    c f ( u , v ) = c ( u , v ) f ( u , v ) {\displaystyle c_{f}(u,v)=c(u,v)-f(u,v)}
    c f ( v , u ) = f ( u , v ) {\displaystyle c_{f}(v,u)=f(u,v)}
  2. c f ( u , v ) = 0 {\displaystyle c_{f}(u,v)=0} nếu không phải.
Đồ thị còn dư là đồ thị G f = ( ( V , E f ) , c f | E f , s , t ) {\displaystyle G_{f}=((V,E_{f}),c_{f}|_{E_{f}},s,t)} , trong đó
E f = { ( u , v ) V × V : c f ( u , v ) > 0 } {\displaystyle E_{f}=\{(u,v)\in V\times V:c_{f}(u,v)>0\}} .
Một đường tăng luồng là một đường s t {\displaystyle s-t} trên đồ thị còn dư G f {\displaystyle G_{f}} .
Định nghĩa dist ( v ) {\displaystyle \operatorname {dist} (v)} là độ dài đường đi ngắn nhất (tính theo số cung) từ s {\displaystyle s} đến v {\displaystyle v} trên G f {\displaystyle G_{f}} . Đồ thị tầng của G f {\displaystyle G_{f}} là đồ thị G L = ( V , E L , c f | E L , s , t ) {\displaystyle G_{L}=(V,E_{L},c_{f}|_{E_{L}},s,t)} , trong đó
E L = { ( u , v ) E f : dist ( v ) = dist ( u ) + 1 } {\displaystyle E_{L}=\{(u,v)\in E_{f}:\operatorname {dist} (v)=\operatorname {dist} (u)+1\}} .
Một luồng ngăn chặn là một luồng f {\displaystyle f'} từ s {\displaystyle s} đến t {\displaystyle t} trên đồ thị G L {\displaystyle G_{L}} sao cho đồ thị G = ( V , E L , s , t ) {\displaystyle G'=(V,E_{L}',s,t)} với E L = { ( u , v ) : f ( u , v ) < c f | E L ( u , v ) } {\displaystyle E_{L}'=\{(u,v):f'(u,v)<c_{f}|_{E_{L}}(u,v)\}} không có đường s t {\displaystyle s-t} nào.

Thuật toán

Thuật toán Dinitz

Dữ liệu vào: Mạng G = ( ( V , E ) , c , s , t ) {\displaystyle G=((V,E),c,s,t)} .
Dữ liệu ra: Một luồng f {\displaystyle f} từ s {\displaystyle s} đến t {\displaystyle t} có giá trị lớn nhất.
  1. Khởi tạo f ( e ) = 0 {\displaystyle f(e)=0} với mọi e E {\displaystyle e\in E} .
  2. Xây dựng G L {\displaystyle G_{L}} từ G f {\displaystyle G_{f}} của G {\displaystyle G} . Nếu dist ( t ) = {\displaystyle \operatorname {dist} (t)=\infty } , thì dừng và đưa ra kết quả f {\displaystyle f} .
  3. Tìm luồng ngăn chặn f {\displaystyle f'} trong G L {\displaystyle G_{L}} .
  4. Tăng luồng   f {\displaystyle \ f} bằng cách thêm f {\displaystyle f'} và quay lại bước 2.

Phân tích

Có thể chứng minh rằng khoảng cách (tính theo số cung) từ đỉnh phát đến đỉnh thu tăng lên ít nhất 1 sau mỗi lần tăng luồng bằng luồng ngăn chặn nên chỉ cần tìm không quá n 1 {\displaystyle n-1} luồng ngăn chặn, trong đó n {\displaystyle n} là số đỉnh của đồ thị. Có thể xây dựng đồ thị tầng G L {\displaystyle G_{L}} bằng tìm kiếm theo chiều rộng trong thời gian O ( E ) {\displaystyle O(E)} và có thể tìm luồng ngăn chặn trong thời gian O ( V E ) {\displaystyle O(VE)} . Do đó thời gian chạy của thuật toán Dinitz là O ( V 2 E ) {\displaystyle O(V^{2}E)} .

Bằng cách sử dụng cấu trúc dữ liệu cây động, có thể giảm thời gian tìm mỗi luồng ngăn chặn xuống còn O ( E log V ) {\displaystyle O(E\log V)} và do đó giảm thời gian chạy của thuật toán Dinitz xuống O ( V E log V ) {\displaystyle O(VE\log V)} .

Trường hợp đặc biệt

Trong mạng với khả năng thông qua đơn vị, thời gian chạy của thuật toán nhanh hơn rất nhiều so với trường hợp tổng quát. Có thể tìm mỗi luồng ngăn chặn trong thời gian O ( E ) {\displaystyle O(E)} , và có thể chứng minh rằng số lần tìm luồng ngăn chặn là không quá số nhỏ hơn giữa O ( E ) {\displaystyle O({\sqrt {E}})} O ( V 2 / 3 ) {\displaystyle O(V^{2/3})} . Do đó thuật toán chạy trong thời gian O ( min ( V 2 / 3 , E 1 / 2 ) E ) {\displaystyle O(\min(V^{2/3},E^{1/2})E)} .

Trong mạng lưới xây dựng từ bài toán ghép cặp trên đồ thị hai phía, số lần tìm luồng ngăn chặn là O ( V ) {\displaystyle O({\sqrt {V}})} , nên thời gian chạy là không quá O ( V E ) {\displaystyle O({\sqrt {V}}E)} . Thuật toán này còn được biết đến là thuật toán Hopcroft–Karp. Tổng quát hơn, chặn trên cho thời gian chạy này đúng cho mọi mạng đơn vị — mạng trong đó mỗi đỉnh, ngoại trừ đỉnh phát và đỉnh thu, hoặc có đúng một cung vào với khả năng thông qua bằng một, hoặc đúng một cung ra với khả năng thông qua bằng một và tất cả các cung khác có khả năng thông qua là số nguyên tùy ý.[2]

Ví dụ

Dưới đây là một ví dụ thực hiện thuật toán Dinitz. Trong đồ thị tầng G L {\displaystyle G_{L}} , nhãn đỏ của các đỉnh là các giá trị dist ( v ) {\displaystyle \operatorname {dist} (v)} . Các đường màu xanh tạo thành một luồng ngăn chặn.

G {\displaystyle G} G f {\displaystyle G_{f}} G L {\displaystyle G_{L}}
1.

Luồng ngăn chặn bao gồm

  1. { s , 1 , 3 , t } {\displaystyle \{s,1,3,t\}} với 4 đơn vị luồng,
  2. { s , 1 , 4 , t } {\displaystyle \{s,1,4,t\}} với 6 đơn vị luồng, và
  3. { s , 2 , 4 , t } {\displaystyle \{s,2,4,t\}} với 4 đơn vị luồng.

Do đó luồng ngăn chặn có 14 đơn vị luồng và tổng giá trị luồng | f | {\displaystyle |f|} là 14. Ghi chú là mỗi đường tăng luồng có 3 cung.

2.

Luồng ngăn chặn bao gồm

  1. { s , 2 , 4 , 3 , t } {\displaystyle \{s,2,4,3,t\}} với 5 đơn vị luồng.

Do đó luồng ngăn chặn có 5 đơn vị luồng và tổng giá trị luồng | f | {\displaystyle |f|} là 14 + 5 = 19. Ghi chú là mỗi đường tăng luồng có 4 cung.

3.

Vì không thể đến được t {\displaystyle t} trong đồ thị G f {\displaystyle G_{f}} , thuật toán kết thúc và trả về kết quả 19. Ghi chú là trong mỗi luồng ngăn chặn, số cung của mỗi đường tăng luồng tăng lên ít nhất một 1.

Lịch sử

Thuật toán Dinitz được xuất bản năm 1970 bởi nhà nghiên cứu khoa học máy tính người Nga (khi đó) Yefim (Chaim) A. Dinitz, nay là thành viên của khoa Khoa học Máy tính tại đại học Ben-Gurion (Israel), trước thuật toán Edmonds–Karp, xuất bản năm 1972 nhưng được phát hiện trước đó. Họ chứng minh một cách độc lập rằng trong thuật toán Ford–Fulkerson, nếu mỗi đường tăng luồng luôn là đường tăng ngắn nhất, chiều dài của đường tăng luồng là không giảm.

Xem thêm

Ghi chú

  1. ^ Yefim Dinitz (1970). “Algorithm for solution of a problem of maximum flow in a network with power estimation” (PDF). Doklady Akademii nauk SSSR. 11: 1277–1280.
  2. ^ Tarjan 1983, tr. 102.

Tham khảo

  • Yefim Dinitz (2006). “Dinitz' Algorithm: The Original Version and Even's Version”. Trong Oded Goldreich, Arnold L. Rosenberg, and Alan L. Selman (biên tập). Theoretical Computer Science: Essays in Memory of [[Shimon Even]] (PDF). Springer. tr. 218–240. ISBN 978-3-540-32880-3. Bản gốc (PDF) lưu trữ ngày 20 tháng 8 năm 2016. Truy cập ngày 14 tháng 9 năm 2012. Tựa đề URL chứa liên kết wiki (trợ giúp)Quản lý CS1: nhiều tên: danh sách biên tập viên (liên kết)
  • Tarjan, R. E. (1983). Data structures and network algorithms.
  • B. H. Korte, Jens Vygen (2008). “8.4 Blocking Flows and Fujishige's Algorithm”. Combinatorial Optimization: Theory and Algorithms (Algorithms and Combinatorics, 21). Springer Berlin Heidelberg. tr. 174–176. ISBN 978-3-540-71844-4.