KruskalAlgorithm Et := 0;tailieudientu.lrc.tnu.edu.vn/Upload/Collection/brief... · 2017-11-27 ·...

10
KruskalAlgorithm Et := 0 ; while I Et < (n— 1) and ( E * 0 ) do { Chọn e là cạnh có độ dài nhỏ nhất trong E; E:= E\{e}; if ( Er u (eỊ không chứa chu trình) then Ex:=ETvj{e}; } if (I Ex I < n-1 ) then Đồ thị không liên thông; Ví dụ: Tìm cây khung nhò nhất cho đồ thị sau đây: Quá trình thực hiện thuật toán được mô tả trong bảng sau đây: 330

Transcript of KruskalAlgorithm Et := 0;tailieudientu.lrc.tnu.edu.vn/Upload/Collection/brief... · 2017-11-27 ·...

Page 1: KruskalAlgorithm Et := 0;tailieudientu.lrc.tnu.edu.vn/Upload/Collection/brief... · 2017-11-27 · thuật toán sẽ đòi hòi thời gian 0(m + p logm) cho việc sắp xếp các

K ruskalA lgorithm

Et := 0 ;

while I E t Ị < (n— 1) and ( E * 0 ) do

{Chọn e là cạnh có độ dài nhỏ nhất trong E;

E:= E \{e};

if ( Er u (eỊ không chứa chu trình) then E x := E T vj{e};

}if ( I Ex I < n-1 ) then Đồ thị không liên thông;

Ví dụ:

Tìm cây khung nhò nhất cho đồ thị sau đây:

Quá trình thực hiện thuật toán được mô tả trong bảng sau đây:

330

Page 2: KruskalAlgorithm Et := 0;tailieudientu.lrc.tnu.edu.vn/Upload/Collection/brief... · 2017-11-27 · thuật toán sẽ đòi hòi thời gian 0(m + p logm) cho việc sắp xếp các

331

Page 3: KruskalAlgorithm Et := 0;tailieudientu.lrc.tnu.edu.vn/Upload/Collection/brief... · 2017-11-27 · thuật toán sẽ đòi hòi thời gian 0(m + p logm) cho việc sắp xếp các

Xét cạnh (h,g).Et = {(a,d), (c,c), (i,h), (h,0, (h,g)}.

Xét cạnh (b,c).Et = {(a,d), (e,c), (i,h), (h,f), (h,g), (b,c)}.

Xét cạnh (b,f)-Er = {(a,d), (e,c), (i,h), (h,f), (h,g), (b,c),

332

Page 4: KruskalAlgorithm Et := 0;tailieudientu.lrc.tnu.edu.vn/Upload/Collection/brief... · 2017-11-27 · thuật toán sẽ đòi hòi thời gian 0(m + p logm) cho việc sắp xếp các

Xét cạnh (b,e).Cạnh (b,e) không được chọn.Et = {(a,d), (e,c), (i,h), (h,f), (h,g), (b,c), (b,f)}.

Xét cạnh (i,e).Cạnh (i,e) không được chọn.E t = {(a,d), (e,c), (i,h), (h,f), (h,g), (b,c), (b ,f)} .

Xét cạnh (c,d).E t = { (a ,d ) , (e ,c ) , ( i ,h ) , (h ,f ) , (h ,g ) , (b ,c ),

( b ,n , ( c ,d ) } .

Thuật toán kết thúc.

Tập cạnh cùa cây khung nhỏ nhất:

Et = {(a,d), (e,c), (i,h), (h,0, (h,g), (b,c), (b,f), (c,d)} Độ dài cùa cây khung nhó nhất:

C ( T ) = 1 + 1 4 - 1 + 2 + 2 + 3 + 5 = 1 5

333

Page 5: KruskalAlgorithm Et := 0;tailieudientu.lrc.tnu.edu.vn/Upload/Collection/brief... · 2017-11-27 · thuật toán sẽ đòi hòi thời gian 0(m + p logm) cho việc sắp xếp các

7 .5 .2 . c ắ u trúc d ữ liệu b iể u d iễ n p hản h o ạ c h

Trong thuật toán, bước đòi hỏi khối lượng tính toán lớn là bước sáp xếp các cạnh của đồ thị theo thứ tự không giám của độ dài. Đối với đồ thị có m cạnh, bước này đòi hói thời gian ớ(mlogm). Tuy nhiên, để xây dựng cây khung nhỏ nhất với n - 1 cạnh, nói chung ta không cần phải sắp thứ tự toàn bộ các cạnh mà chi cần xét phần trên cùa dãy đó chứa p < m cạnh. Do đó thay vì sắp xếp toàn bộ dãy cạnh ta sẽ sử dụng heap-min. Theo cách làm này, để tạo đống đầu tiên ta mất thời gian O(m), việc vun lại đống sau khi lấy ra phần tử ở gốc đòi hòi thời gian ơ(logm). Vì vậy, với cải tiến này, thuật toán sẽ đòi hòi thời gian 0(m + p logm) cho việc sắp xếp các cạnh. Trong việc giải các bài toán thực tế, số p thường nhỏ hơn rất nhiều so với m.

Vấn đề thứ hai trong việc thể hiện thuật toán Kruskal là việc lựa chọn cạnh để bồ sung đòi hòi phải có một thủ tục hiệu quả kiềm tra tập cạnh £ y u {e} có chứa chu trình hay không. Đe ý rằng, các cạnh trong E j ở các bước lặp trung gian sẽ tạo thành một rùng. Cạnh e cần khảo sát sẽ tạo thành chu trinh với các cạnh trong E T khi và chi khi cả hai đinh đầu của nó thuộc vào cùng một cây con của rừng nói trên. Do đó, nếu cạnh e không tạo thành chu trình với các cạnh trong ET, thì nó phải nổi hai cây khác nhau trong £y. Vi thế, đề kiểm tra xem có thể bổ sung cạnh e vào Et hay không, ta chi cần kiểm tra xem nó có nối hai cây khác nhau trong T hay không. Một trong các phương pháp hiệu quả để thực hiện việc kiểm tra này là ta sẽ phân hoạch tập các đinh của đồ thị ra thành các tập con không giao nhau, mỗi tập xác định bởi một cây con trong T (được hình thành ờ các bước do việc bồ sung cạnh vào T).

Như vậy, để giải quyết vấn đề thứ hai này, ta phải xây dựng hai thù tục: Kiểm tra xem hai đầu u, V của cạnh e - (u, v) có thuộc vào hai tập con khác nhau hay không và trong trường hợp câu trả lời là khẳng định, nối hai tập con tương ứng thành một tập. cấu trúc dữ liệu biểu diễn các tập không giao nhau có thế sử dụng để đáp ứng yêu cầu này,

Cấu trúc dữ liệu mô tả các tập không giao nhau(Disjoint Set Data Structures)

Cho tập v= {1, 2,..., ri). Chúng ta cần xây dựng cấu trúc dữ liệu mô tả các tập con trong phân hoạch của tập V và các phép toán cơ bản sau đây đối với cấu trúc dữ liệu:

- M a k e se t(x ) - tạ o m ộ t tậ p c o n c h ứ a d u y n h ấ t p h ần tử X.

- U n io n (x ,y ) - th a y hai tậ p c h ứ a X v à y bở i tập là h ợ p củ a ch ú n g .

- Find(x) - trả lại tên của tập con chứa X. Để đặt tên cho các tập con, ta có thể sừ dụng một phần từ nào đó của nó.

Trước hết để biểu diễn mỗi tập con X c V, chúng ta sẽ sử dụng cấu trúc cây có gốc: chọn một phần tử nào đó cùa X làm gốc (tên của tập con X chính là phần tử tương ứ n g vớ i g ố c ), m ỗ i p h ầ n từ X e X sẽ c ó m ộ t b iến trỏ p a ren tỊx ] trò đ ến c h a c ủ a nó, n ế u X

là g ố c thì p a ren tỊx ] = X.

334

Page 6: KruskalAlgorithm Et := 0;tailieudientu.lrc.tnu.edu.vn/Upload/Collection/brief... · 2017-11-27 · thuật toán sẽ đòi hòi thời gian 0(m + p logm) cho việc sắp xếp các

Ví dụ: Giả sử có v= {1,2, 3, 4 , 5,6, 7, 8, 9}, K| = {1, 3, 4}, v2 = {2, 5, 6, 7, 9}, = Ị K}. Ta c ó ba cây mô tả ba tập V\, Vị, Vị.

©

©

Cây tirơng ứng với K| Cây tương ứng với K2 Cây tương ứng với Vị

Màng parent đề biểu diễn rừng gồm ba cây tương ứng với V ị , y 2, Vy.

i 1 2 3 4 5 6 7 8 9

parent 1 2 1 3 2 5 2 8 5

Như vậy, thủ tục MakeSet(x) có thổ viết như sau:procedure MakeSet(x)beginparcntfx] := x;

end;Pc tìm tên của tập con chứa phần từ X, ta dùng hàm sau:

function Find(x); begin

w h i l o X - ý - p a r e n t f x ] d o X = p n r e n t [ x ] *

Find:= x;end;

Đổ nối tập con chứa X và tập con chứa y, chúng ta có thể chữa lại biến trỏ củagốc của cây chứa X để nó tró đến gốc của cây con chứa y . Điều đó được thực hiện nhờthủ tục sau:

p ro ced u re Union(x, y); begin

u:= Finđ(x); (* Tìm u là gốc củd cây ton chứa X *)v:= Find(y); (* Tìm V là gốc cùa cây con chứa y *)parent[u] := v;

end;

335

Page 7: KruskalAlgorithm Et := 0;tailieudientu.lrc.tnu.edu.vn/Upload/Collection/brief... · 2017-11-27 · thuật toán sẽ đòi hòi thời gian 0(m + p logm) cho việc sắp xếp các

Có thể thấy thời gian tính của hàm Find(x) phụ thuộc vào độ cao của cây chứa X. Trong trường hợp cây có k đình và được biểu diễn như một đường đi (xem cây Vi) thì độ cao của cây sẽ là Ả' - 1. Từ đó suy ra hàm Find(x) có đánh giá thời gian tính là 0(n).

Liệu có cách nào để giám độ cao của các cây con? Có một cách thực hiện rât đơn giản: khi nối hai cây chúng ta sẽ điều chinh con trỏ cùa gốc của cây con có ít đinh hơn, chứ không thực hiện việc nối một cách tùy tiện. Đe ghi nhận số phần tử cùa một cây, chúng ta sẽ sử dụng thêm biến Num[v] chứa số phần từ của cây con với gốc tại V.

Khi đó cần sửa lại thủ tục MakeSet(x) và Union(x, y) như sau:

procedure MAKESET(x)

beginparentỊx] := x; Num[x]:=l;

end;

procedure U n io n (x , y);

beginu:= Find(x); (* Tìm u là gốc của cây con chứa X *)

v := F in d (y ); (* T ìm V gốc c ủ a cây co n c h ứ a y *)

if Num[u] <= Num[v] then

begin

parent[u] :=v; Num[u]:= Num[u]+Num[v];

end

else

beginp a re n t[v ] := u;

N u m [v ]:= N u m [u ]+ N u m [v ];

end

end;

Ta có kết quà sau đây.

Bổ đề 2: Giả sừ quá trình thực hiện nối cây bắt đầu từ các cày chi có một đỉnh. Khi đó độ cao của các cây xuất hiện khi thực hiện thủ tục nối không vượt quá log/ỉ.

Chứng minh: Ta chứng minh bang quy nạp theo n là số đinh của cây. Rõ ràng bổ đề là đúng cho n = 1. Già sừ bồ đề là đúng cho cây với số đình ít hơn II. Xét cây T có n đỉnh. Do cây T được gộp từ hai cây với số đinh ít hon n, nên nếu gọi Tị và Tĩ là hai cây với số đinh tương ứng là m và n - p gộp thành cây T, thì ta có p < n/2.

336

Page 8: KruskalAlgorithm Et := 0;tailieudientu.lrc.tnu.edu.vn/Upload/Collection/brief... · 2017-11-27 · thuật toán sẽ đòi hòi thời gian 0(m + p logm) cho việc sắp xếp các

I

Từ giả thiết quy nạp, ta suy ra cây T có độ cao là:

m ax { d e p U T |)+ 1 , d e p th (7 2 )}

< max {[log m] + 2, [log(íi-m)] +1}< max {[log m] + 2, [log n] +1}

= [log «] +1.Bô đê được chứng minh.Từ bổ đề suy ra các thao tác Find và Union được thực hiện với thời gian 0(log/i)

nhờ sử dụng cách nối cây trình bày sau cùng.

Thuật toán Kruskal với cấu trúc dữ liệu vừa trình bày có thể mô tả như sau:

Kruskal_UF

// K-hời tạo

1 . E t 02. for ve V do3. Make-Set(v);

4. Sắp xếp các cạnh trong E theo thứ tự không giảm cùa trọng số

/ / Vòng lặp

5. for (u,v) 6 £ do

6. if Find(w) # Find(v)

7. then ET <r- Er u {(w,v)};

8. Union(w,v);

9 . i f ( \ E t \ < n - \ )

then Đồ thị không liên thông;

else E t là tập cạnh cùa cây khung nhò nhất;

337

Page 9: KruskalAlgorithm Et := 0;tailieudientu.lrc.tnu.edu.vn/Upload/Collection/brief... · 2017-11-27 · thuật toán sẽ đòi hòi thời gian 0(m + p logm) cho việc sắp xếp các

Phân tích thời gian tính của thuật toán Kruskal_UF

-D òng 1 - 3 : Ỡ(|K|).- Dòng 4 (sắp xếp danh sách cạnh): 0(\E\ log |£|).- Dòng 6 - 8 (các thao tác với phân hoạch phải lặp lại không quá |£| lần): 0(\E\

log |£|).Tồng cộng: Ũ(\E\ log |£|).Đối với đồ thị thưa, thuật toán nên sử dụng cách cài đạt vừa trình bày đê giải bài

toán cây khung nhỏ nhất.

7.6 . BÀI TOÁN Đ Ư Ờ N G ĐI NGÁN NHÁT

Cho đồ thị có trọng số trên cạnh. Trọng số trên cạnh của đồ thị có thê là chi phí đề khảo sát cạnh đó. Chẳng hạn, nếu đồ thị biểu diễn sơ đồ giao thông (các đinh tương ứng vói các nút giao thông, các cạnh tương ứng với các đoạn đường phố nối các cặp nút giao thông), thi trọng số trên cạnh có thể là khoảng cách, chi phí đi lại hoặc thời gian đi lại giữa hai nút giao thông.

Đối với đồ thị như vậy, chúng ta thường phải trà lời cho các câu hói như:

- Đi từ A đến B theo đường nào là nhanh nhất?- Đi từ A đến B theo đường nào là rè nhất?- Đi từ A đến B theo đường nào là ngắn nhất?Mỗi câu hòi như vậy là đầu vào cho cùng một bài toán: Bài toán đường đi ngắn

nhất (shortest path problem).Để phát biểu một cách chính xác hơn bài toán đường đi ngắn nhất, ta cần đưa

v à o m ộ t số khái n iệm .

Định nghĩa: Cho đồ thị có hướng G — (V, E) với trọng số trên cạnh c(e), e 6 E.G ià sir s. t e. V và P{s. i) là điròrng đi từ s đến t trên đ ồ th i:

P(s,ty. s = Vo, V*_|, V* = t.

Ta gọi độ dài của đường đi P(s, t) là tổng trọng số trên các cung của nó, tức là nếu ký hiệu p(P(s,t)), thì theo định nghĩa:

p (P (s , t ) ) = Y , c(e) = Z c(v<’ ví+')-eeP(í.l) i=0

Ta gọi đường đi ngắn nhất từ s đến t là đường đi có độ dài nhỏ nhất trong số tâtcả các đường đi từ 5 đến t trên đồ thị.

Người ta thường sứ dụng ký hiệu ỗ(s,t) đề chi độ dài cùa đường đi ngắn nhất từ s đến t và gọi nó là khoảng cách từ s đến I.

Có ba dạng bài toán đường đi ngắn nhất cơ bản.

338

Page 10: KruskalAlgorithm Et := 0;tailieudientu.lrc.tnu.edu.vn/Upload/Collection/brief... · 2017-11-27 · thuật toán sẽ đòi hòi thời gian 0(m + p logm) cho việc sắp xếp các

Bái toán 1: Tim đường đi ngăn nhát giữa hai đình cho trước.Bài toán 2: Tìm đường đi ngắn nhất từ một đỉnh nguồn s đến tất cà các đình

ícòn lại.Bài toán 3: Tìm đường đi ngắn nhất giữa hai đỉnh bất ki.Trước hết, dễ thấy các bài toán được dẫn ra theo thứ tự từ đơn giản đến phức tạp

hơn. Mặt khác cũng có thể thấy ngay là nếu ta có thuật toán để giải một trong ba bài toán thì thuật toán đó cùng có thể sư dụng đề giải hai bài toán còn lại.

Đường đi ngắn nhất giữa hai đinh nào đó có thể không tồn tại. Chẳng hạn, nếu không có đường đi từ s đến I, thì rõ ràng cũng không có đường đi ngắn nhất từ s đến t. Ngoài ra, nếu đồ thị chứa cạnh c ó trọng số âm thì có thể xảy ra tình huống: độ dài đường đi giữa hai đinh nào đó có thể làm nhỏ tùy ý. Ta xét ví dụ sau đây.

Ví dụ: Xét đồ thị có trọng số.

Xét đường đi từ a đến b:

a, k(h, c, d, b), e.

Nghĩa là ta đi k lần vòng theo chu trình

C: b, c, d, b

trước khi đến e. Độ dài của đường đi này băng:

c(a,b) + k /XO + c(b,e) = 2 -10A: —► -00 , khi k —> +00.

Tồng quát, nếu trên đường đi từ 5 đến t ta có thể đi vòng quanh một chu trình có đ ộ dài â m (ch u tr ìn h n h ư v ậy đ ư ợ c gọi là ch u tr ìn h âm ) th ì đ ộ dài củ a đ ư ờ n g đi từ s đ ến

t có th ể làm n h ò tù y ý. T ro n g trư ờ n g hợp n ày đ ư ờ n g đ i n g ắ n n h ấ t từ .V đ ế n t là k h ô n g

tồ n tại.

Dỗ thấy rằng, nếu như trọng số trẽn các cạnh là các số không âm: cịe) > 0, e 6 E, thì không tồn tại chu trình âm và nếu có đường đi từ s đến t thì luôn có đường đi ngan n h ấ t từ s đến t.

Trong mục tiếp theo chúng ta sẽ trình bày thuật toán Dijkstra để giải bài toán 2.

339