Minimalne drzewo rozpinaj¡ce
Transkrypt
Minimalne drzewo rozpinaj¡ce
Minimalne drzewo rozpinaj¡ce dr Andrzej Mróz (UMK w Toruniu) 2013 Projekt wspóªnansowany ze ±rodków Unii Europejskiej w ramach Europejskiego Funduszu Spoªecznego Projekt pn. Wzmocnienie potencjaªu dydaktycznego UMK w Toruniu w dziedzinach matematyczno-przyrodniczych Poddziaªanie 4.1.1 Programu Operacyjnego Kapitaª Ludzki 2 Spis tre±ci 1 Wst¦p 3 1.1 Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2 Drzewo rozpinaj¡ce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.3 Drzewo rozpinaj¡ce przykªad . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.4 Minimalne drzewo rozpinaj¡ce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.5 Minimalne drzewo rozpinaj¡ce przykªad . . . . . . . . . . . . . . . . . . . . . . 4 1.6 Cel - poszukiwanie MST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2 Idee 5 2.1 Strategia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2 Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.3 Idea algorytmu Kruskala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.4 Idea algorytmu Prima 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Zbiory rozª¡czne 7 3.1 Struktury danych dla zbiorów rozª¡cznych . . . . . . . . . . . . . . . . . . . . . . 3.2 Proste zastosowanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 3.3 Heurystyka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 3.4 Implementacja listy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.5 Implementacja drzewa z korzeniem . . . . . . . . . . . . . . . . . . . . . . . . . 9 4 Kruskal 7 11 4.1 Poprawno±¢ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Przekroje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 4.3 Algorytm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 4.4 Przebieg algorytmu Kruskala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Prim 11 13 14 5.1 Poprawno±¢ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 5.2 Implementacja 15 5.3 Algorytm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 5.4 Przebieg algorytmu Prima . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1 Wst¦p 1.1 Problem Ustalmy spójny niezorientowany graf G = (V, E) Rozwa»my nast¦puj¡c¡ interpretacj¦ grafu V = {1, 2, . . . , n} z funkcj¡ wagi w : E → R+ . G: • wierzchoªki • kraw¦dzie = potencjalne bezpo±rednie drogowe poª¡czenia pomi¦dzy miastami, • waga w(i, j) kraw¦dzi {i, j} ∈ E Zagadnienie optymalizacyjne. (czyli wybra¢ podgraf G0 = miasta, grafu G) = koszt budowy poª¡czenia pomi¦dzy miastami i i j. Zbudowa¢ tylko te drogi spo±ród opisanych przez graf G tak, by: 1. pomi¦dzy ka»d¡ par¡ miast (wierzchoªków) istniaªo drogowe poª¡czenie (niekoniecznie bezpo±rednie), 2. koszt budowy tej sieci dróg byª najni»szy spo±ród wszystkich rozwi¡za« speªniaj¡cych punkt 1. atwo zauwa»y¢, »e je»eli podgraf G0 speªnia te wªasno±ci, to 1. zawiera wszystkie wierzchoªki grafu G, 2. jest spójny, 3. nie zawiera cykli. W szczególno±ci 2 i 3 oznaczaj¡, »e rozpinaj¡cym, G0 powinien by¢ drzewem. Tzw. minimalnym drzewem które za chwil¦ zdeniujemy w sposób bardziej formalny. Problem ten pojawia si¦ w wielu innych kontekstach informatycznych, cz¦sto znalezienie minimalnego drzewa rozpinaj¡cego jest pierwszym krokiem w rozwi¡zaniach innych problemów. Czasem stosuje si¦ te» nazw¦ minimalne drzewo spinaj¡ce. 1.2 Drzewo rozpinaj¡ce Niech G = (V, E) E0 b¦dzie spójnym grafem niezorientowanym. Denicja. Drzewo rozpinaj¡ce (ang. spanning tree) grafu G = drzewo T = (V, E 0 ) takie, »e ⊆ E. Tzn. T jest drzewem zawieraj¡cym wszystkie wierzchoªki podzbiorem zbioru kraw¦dzi 1.3 G, za± jego zbiór kraw¦dzi jest G. • Drzewo rozpinaj¡ce powstaje z grafu • Ka»de drzewo rozpinaj¡ce grafu G G ma poprzez usuni¦cie kraw¦dzi nale»¡cych do cykli. |V | − 1 Drzewo rozpinaj¡ce przykªad Drzewo rozpinaj¡ce nie jest poj¦ciem jednoznacznym. kraw¦dzi. 4 Dla grafu G: v f @ @ f v f v @v f f v f v f v @v f f v f v f v f v f v f v f v f v f v f v f v f v f v @ f v Drzewem rozpinaj¡cym jest podgraf T: v f @ @ @ f v Ale te» podgraf Oraz podgraf T2 : T3 : 1.4 Minimalne drzewo rozpinaj¡ce Niech G = (V, E) b¦dzie spójnym grafem niezorientowanym z wag¡ T = (V, E 0 ) grafu G X w(T ) = w(u, v). Dla dowolnego drzewa rozpinaj¡cego w : E → R+ . deniujemy jego wag¦ (u,v)∈E 0 Denicja. Minimalne drzewo rozpinaj¡ce drzewo rozpinaj¡ce T (ang. w(T ) o minimalnej wadze minimal spanning tree G). 1.5 Minimalne drzewo rozpinaj¡ce przykªad Dla grafu z wagami: v 2 f f v @ 1 @ 15 2 @ @v f v f 13 f v 9 10 8 f v przykªadowe wagi drzew rozpinaj¡cych: T : v f @ @ 2 v f f v 1 @ 13 @v f MST) grafu G = (spo±ród wszystkich drzew rozpinaj¡cych grafu f v w(T ) = 35 9 10 f v T2 : 5 2 f v f v 15 8 f v f v 13 2 f v Nietrudno sprawdzi¢, »e dla powy»szego grafu f v 8 w(T3 ) = 33 f v G minimalnym drzewem rozpinaj¡cym jest T3 . T3 : nie jest jedynym MST. Inne drzewo rozpinaj¡ce o tej samej wadze co v f @ @ T4 : 2 v f 1.6 9 f v 13 w(T2 ) = 48 f v 1 f v T3 10 f v T3 : Ale zauwa»my, »e f v f v f v 1 @ 13 9 @v f 8 w(T4 ) = 33 f v Cel - poszukiwanie MST Rozwi¡zanie naiwne: Wygenerowa¢ wszystkie drzewa rozpinaj¡ce i wybra¢ te o najmniejszej wadze. Oczywista wada: Drzew rozpinaj¡cych jest na ogóª bardzo du»o. Ponadto, wcale nie jest to takie proste pod wzgl¦dem implementacyjnym. Cel: 2 Opracowa¢ efektywn¡ metod¦ znajdowania (jakiegokolwiek) MST. Idee 2.1 Strategia Ogólna strategia zachªanna rozrastanie si¦ podgrafu T o zbiorze kraw¦dzi A, który na ko«cu b¦dzie MST. Dane: Cel: Spójny graf niezorientowany Znalezienie MST dla G = (V, E) w : E → R+ . G. • Podgraf • W czasie algorytmu trzymamy zbiór T z funkcj¡ wagow¡ rozrasta si¦ w wyniku dodawania kolejnych kraw¦dzi. A, który zawsze jest podzbiorem zbioru kraw¦dzi pewnego MST. • W ka»dym kroku wyznaczamy kraw¦d¹, któr¡ mo»na doda¢ do no±ci (kraw¦d¹ bezpieczn¡ dla A). A bez straty jego wªas- 6 B¦dziemy zatem realizowa¢ strategi¦ opisan¡ przez bardzo ogólny pseudokod: GenericMST(G, w) 1 begin ∅; 2 A := 3 while A 4 nie tworzy drzewa rozpinaj¡cego do begin znajd¹ kraw¦d¹ {u, v} ∈ E\A bezpieczn¡ dla A; ∪ { {u, v} } 5 6 A := A 7 end 8 end; Poprawno±¢ ogólnie: • Niezmiennik A jest podzbiorem zbioru kraw¦dzi pewnego MST jest zachowany w ka»dym kroku. • 2.2 Kraw¦d¹ bezpieczna w ka»dym kroku istnieje gwarantuje to niezmiennik. Problem Gªówny problem. Jak rozpoznawa¢ bezpieczn¡ kraw¦d¹? Omówimy dwa ró»ne rozwi¡zania tego problemu, tj. dwie ró»ne realizacje ogólnej strategii GenericMST: 2.3 • Algorytm Kruskala. • Algorytm Prima. Idea algorytmu Kruskala Nieformalny opis • W ka»dym kroku rozrastaj¡cy si¦ podgraf T = (V, A) grafu G jest lasem (tj. jego skªadowe s¡ drzewami). • Na pocz¡tku • Dodaj¡c bezpieczn¡ kraw¦d¹ do • Na ko«cu • W poszukiwaniu kraw¦dzi bezpiecznych w kolejnych krokach przetwarzamy kraw¦dzie T A = ∅, tj. skªadowe T A to jednowierzchoªkowe drzewa. scalamy dwie skªadowe T w jedn¡. scali si¦ w jedno drzewo. w kolejno±ci ich rosn¡cych (niemalej¡cych) wag. • Kraw¦d¹ e jest bezpieczna, gdy dodanie jej do (jest to równowa»ne z tym, »e e A nie spowoduje pojawienia si¦ cyklu ª¡czy dwie ró»ne dotychczasowe skªadowe w Nale»y zatem umie¢ rozpoznawa¢ ró»ne skªadowe w grae struktur¦ danych, tzw. struktur¦ zbiorów rozª¡cznych. T. T ). Do tego wykorzystamy now¡ 7 2.4 Idea algorytmu Prima Nieformalny opis • W odró»nieniu od algorytmu Kruskala, tu • Na pocz¡tku • W ka»dym kroku kraw¦d¹ bezpieczna to kraw¦d¹ o najmniejszej wadze spo±ród kraw¦dzi T wystaj¡cych z T zawsze stanowi jedno drzewo. ma 1 wierzchoªek (dowolnie wybrany z T (tj. ª¡cz¡cych wierzchoªek z T G). z wierzchoªkiem spoza T ). Nale»y zatem umie¢ efektywnie wybiera¢ kraw¦dzie bezpieczne j.w. Do tego wykorzystamy odpowiedni¡ kolejk¦ priorytetow¡. 3 Zbiory rozª¡czne 3.1 Struktury danych dla zbiorów rozª¡cznych W algorytmie Kruskala wykorzystamy nast¦puj¡c¡ dynamiczn¡ struktur¦ danych. Kontekst: n ró»nych elementów pogrupowanych w pewn¡ liczb¦ zbiorów rozª¡cznych. Cel: zdeniowanie i zarz¡dzanie strukturami danych umo»liwiaj¡cymi operacje m.in.: • ª¡czenia dwóch zbiorów, • stwierdzania, do którego zbioru nale»y element • stwierdzania, czy dwa elementy Zarz¡dzanie rodzin¡ Pomysª: x, y S = {S1 , S2 , . . . , Sk } ka»dy zbiór x, nale»¡ do tego samego zbioru. rozª¡cznych zbiorów dynamicznych. Si identykujemy poprzez jego reprezentanta, czyli wyró»niony element x ∈ Si . Warunki nakªadane na reprezentanta: • na ogóª nie ma znaczenia, który element jest reprezentantem, • wa»ne jest, by zadaj¡c dwukrotnie pytanie o reprezentanta danego zbioru, otrzyma¢ tak¡ sam¡ odpowied¹, o ile zbiór w tym czasie si¦ nie zmieniaª, • czasami ustala si¦ na pocz¡tku pewn¡ zasad¦ wyboru reprezentanta (np. element z najmniejszym kluczem...). Podstawowe operacje: • MakeSet(x) tworzy nowy jednoelementowy zbiór S = {x} (o reprezentancie x); x nie mo»e by¢ elementem innego zbioru. • Union(x, zbiór y) Sx ∪ Sy . ª¡czy dwa rozª¡czne zbiory Sx , Sy zawieraj¡ce odpowiednio Jego reprezentantem mo»e by¢ dowolny element xiy w nowy Sx ∪ Sy , na ogóª reprezentant Sx lub Sy . • ⇒ FindSet(x) zwraca wska¹nik do reprezentanta (jedynego) zbioru zawieraj¡cego stwierdzanie, czy dwa elementy FindSet(y). x, y x. nale»¡ do tego samego zbioru: test FindSet(x) = 8 3.2 Proste zastosowanie Przykªad zastosowania: rozpoznawanie spójnych skªadowych w grae (niezorientowanym) G = (V, E). ConnectedComponents(G) 1 begin 2 for ka»dy v ∈ V do 3 MakeSet(v); 4 for ka»da (u, v) 5 ∈ E do if FindSet(u) <> FindSet(v) then 6 Union(u, v); 7 end; Po wykonaniu podziaª wierzchoªków na zbiory rozª¡czne odpowiada podziaªowi na skªadowe spójno±ci. W podobnym kontek±cie wykorzystamy zbiory rozª¡czne w algorytmie Kruskala (który jest de facto pewn¡ modykacj¡ powy»szej procedury). Teraz, do testowania czy wierzchoªki u i v nale»¡ do tej samej skªadowej mo»emy wykorzysta¢ procedur¦: SameComponent(u, v) 1 begin 2 if FindSet(u) = FindSet(v) then 3 return true 4 else return false 5 end; • Wiemy: • do wyznaczania skªadowych mo»na wykorzysta¢ przegl¡danie grafu. Gdy do grafu kraw¦dzie s¡ dodawane w czasie dziaªania algorytmu (czyli trzeba uaktualnia¢ spójne skªadowe), to implementacja przy pomocy zbiorów rozª¡cznych mo»e by¢ efektywniejsza. 3.3 Heurystyka W dalszej cz¦±ci przeprowadzimy prost¡ analiz¦ heurystyczn¡. Przez zowany heurystyk¦ rozumiemy tu takie projektowanie operacji, by zmniejszy¢ ich koszt zamorty- (niekoniecznie koszt pesymistyczny = zªo»ono±¢ pesymistyczn¡). Denicja. Koszt zamortyzowany = koszt ±redni operacji P Uwaga. w ci¡gu n wykona« operacji P. Sªowo heurystyka ma w informatyce równie» inne znaczenia. Przykªad. Wykonujemy kolejno samym zbiorze danych X. n sortowa« algorytmem sortowania b¡belkowego P na tym Wówczas • tylko za pierwszym razem wykonywane s¡ nietrywialne modykacje na • st¡d tu koszt zamortyzowany jest znacznie ni»szy ni» koszt pesymistyczny algorytmu X, P. Oczywi±cie koszt zamortyzowany istotnie zale»y od kontekstu wykonywania danej operacji. 9 3.4 Implementacja listy Implementacja zbiorów rozª¡cznych w postaci list. • Ka»dy zbiór przechowywany jako (dynamiczna) lista. • Pierwszy skªadnik listy = reprezentant zbioru. • Ka»dy skªadnik listy posiada pola: element zbioru, wska¹nik do nast¦pnego skªadnika listy, wska¹nik (prowadz¡cy wstecz) do reprezentanta. MakeSet(x) stworzenie nowej listy o jedynym skªadniku FindSet(x) zwrócenie wska¹nika od Union(x, • y) doª¡czenie listy do reprezentanta zbioru. z elementem y na koniec listy Zªo»ono±¢: O(1). Lx z elementem x. Reprezentantem nowego zbioru jest element b¦d¡cy wcze±niej reprezentantem zbioru zawieraj¡cego • Ly x x. Zªo»ono±¢: O(1). x. Trzeba uaktualni¢ wska¹nik do reprezentanta we wszystkich skªadnikach znajduj¡cych si¦ pierwotnie na li±cie Ly . Zªo»ono±¢: O(s), gdzie s = |Ly | (gdy mamy dost¦p do ostatniego elementu Lx ). Usprawnienie: heurystyka ª¡czenia z wywa»aniem. • Zawsze doª¡czamy krótsz¡ list¦ do dªu»szej. • Trzeba przechowywa¢ (np. w reprezentancie) i uaktualnia¢ rozmiar listy. Asymptotyczna zªo»ono±¢ pojedynczej operacji Union pozostaje taka sama, lecz koszt zowany jest mniejszy. Pokazuje si¦, »e wykonanie ci¡gu m operacji MakeSet, Union i FindSet, spo±ród których to MakeSet zajmuje przy wywa»aniu czas Bez wywa»ania: 3.5 zamortyn O(m + nlog n). O(m2 ). Implementacja drzewa z korzeniem Implementacja w postaci drzew z korzeniem. • Ka»dy zbiór przechowywany jako drzewo z korzeniem. • Korze« drzewa = reprezentant zbioru. • Ka»dy wierzchoªek drzewa posiada pola: element zbioru, wska¹nik do ojca w drzewie (korze« wskazuje na siebie). Struktur¦ drzewa mo»na tak»e zaimplementowa¢ przy wykorzystaniu tablicy ojców indeksowanej elementami, które grupujemy w zbiory. 10 Przykªad. Trzy zbiory rozª¡czne grupuj¡ce 10 elementów, reprezentowane poprzez drzewa: g 1w g 2w g 6w @ @5w g @ @4w g @ g 10w g @9w g 7w g 3w g 8w s¡ jednoznacznie zakodowane przy pomocy tablicy ojców: i 1 2 3 4 5 6 7 8 9 10 ojciec[i] 2 2 6 6 2 6 4 8 4 4 Operacje: MakeSet(x) stworzenie nowego drzewa o jedynym wierzchoªku FindSet(x) przej±cie po wska¹nikach od x x. Zªo»ono±¢: O(1). do ojca itp. a» do korzenia. Zªo»ono±¢: O(h), gdzie h = wysoko±¢ drzewa. Union(x, y) zmiana wska¹nika w korzeniu drzewa Ty (zawieraj¡cego y ). Zªo»ono±¢: O(1) (gdy mamy dost¦p Tx (zawieraj¡cego x) tak aby wskazywaª na korze« drzewa do korzeni). Dwie heurystyki: 1. ¡czenie wg wysoko±ci: drzewo o mniejszej wysoko±ci doª¡czamy do drzewa o wi¦kszej wysoko±ci (+ uaktualnienie wysoko±ci). 2. Kompresja drogi: stosowana przy operacji FindSet(x) polega na zmianie wska¹ników we wszystkich wierzchoªkach na drodze od x do korzenia tak, by wskazywaªy na korze«. Implementacja z uwzgl¦dnieniem heurystyk. Oznaczenia: • h(x) = wysoko±¢ wierzchoªka • ojciec(x) = ojciec wierzchoªka MakeSet(x) 1 2 3 4 begin ojciec(x) := x; h(x) := 0 end; x (∈ N), x (wska¹nik lub odwoªanie do tablicy ojców). 11 ¡czenie wg wysoko±ci. Wykorzystamy procedur¦ pomocnicz¡: Link(x, y) 1 begin 2 if h(x) > h(y) then 3 ojciec(y) := x 4 else begin 5 ojciec(x) := y; 6 if h(x) = h(y) then 7 h(y) := h(y) 8 + 1 end 9 end; Union(x, y) 1 begin 2 Link(FindSet(x), FindSet(y)) 3 end; FindSet z kompresj¡ drogi: FindSet(x) 1 begin 2 if x <> ojciec(x) then 3 ojciec(x) := FindSet( ojciec(x) ); 4 return ojciec(x) 5 end; Uwaga. Zauwa»my, »e po FindSet wysoko±¢ drzewa mo»e ulec zmianie (zmniejszeniu). Mimo to, nie uaktualniamy warto±ci h dla »adnego wierzchoªka. Utrzymywanie poprawnych warto±ci wysoko±ci drzew byªoby niepotrzebnie kosztowne. Zatem warto±ci h nale»y tak naprawd¦ inter- pretowa¢ jako górne ograniczenia wysoko±ci drzew. Zaªó»my, »e wykonujemy ci¡g m operacji MakeSet, Union i FindSet, spo±ród których n to MakeSet. Twierdzenie (Hopcroft, Ullman). Zªo»ono±¢ wykonania ci¡gu powy»szych operacji z uwzgl¦d- nieniem heurystyk 1 i 2 wynosi O(m log∗ n). log∗ = logarytm iterowany. log∗ jest funkcj¡ bardzo wolno rosn¡c¡. log∗ n ≤ 5 dla wszystkich 1 ≤ n ≤ 265536 . Liczba atomów we wszech±wiecie ≈ 1080 < 265536 . 4 4.1 Kruskal Poprawno±¢ Zanim przedstawimy konkretny pseudokod, wprowadzimy kilka poj¦¢ i faktów pozwalaj¡cych zrozumie¢, dlaczego idea algorytmu Kruskala przedstawiona wcze±niej zawsze daje poprawne rozwi¡zanie. 12 Poj¦cia te wyst¦puj¡ te» w innych kontekstach algorytmów grafowych. Bardziej szczegóªowy dowód poprawno±ci mo»na znale¹¢ np. w ksi¡»ce [1] ze spisu literatury do wykªadu (T. H. Cormen et al.). 4.2 Przekroje Denicje: • Ka»dy podzbiór • Kraw¦d¹ S, • a S⊆V wyznacza {u, v} krzy»uje si¦ drugi do V \ S . z przekrojem (S, V \ S) uwzgl¦dnia Przekrój przekrój (S, V \ S) grafu (S, V \ S), zbiór kraw¦dzi A, G = (V, E). je±li jeden z jej ko«ców nale»y do je±li »adna kraw¦d¹ z A nie krzy»uje si¦ z tym przekrojem. • e∈E Kraw¦d¹ krzy»uj¡ca si¦ z przekrojem jest kraw¦dzi¡ lekk¡, je±li w(e) jest najm- niejsza spo±ród wag wszystkich kraw¦dzi krzy»uj¡cych si¦ z tym przekrojem. Przytoczymy bez dowodu kluczowy fakt, na którym opiera si¦ uzasadnienie poprawno±ci obu algorytmów. G = (V, E) spójny graf niezorientowany z funkcj¡ wagow¡ w : E → R+ Twierdzenie Niech • E ⊇ A podzbiór zbioru kraw¦dzi pewnego MST dla G, • (S, V \ S) dowolny przekrój grafu G uwzgl¦dniaj¡cy A, • {u, v} kraw¦d¹ lekka krzy»uj¡ca si¦ z (S, V \ S). Wówczas kraw¦d¹ {u, v} jest bezpieczna dla A. Przypomnienie idei algorytmu: GenericMST(G, w) 1 begin ∅; 2 A := 3 while A 4 do znajd¹ kraw¦d¹ {u, v} ∈ E\A bezpieczn¡ dla A; A := A ∪ { {u, v} } 5 6 7 8 nie tworzy drzewa rozpinaj¡cego begin end end; Rozwa»my graf T = (V, A). W ka»dym kroku jest on acykliczny ⇒ ka»da jego spójna skªadowa jest drzewem. • • na pocz¡tku poniewa» A=∅ ⇒ T skªada si¦ z A ∪ { {u, v} } musi T, |V | jednowierzchoªkowych drzew, {u, v} dla A ª¡cz¡ si¦ (liczba drzew maleje), na ko«cu las T by¢ acykliczny, ka»da bezpieczna kraw¦d¹ ª¡czy ró»ne skªadowe z • w ka»dym kroku kolejne skªadowe zawiera tylko 1 drzewo ⇒ T jest MST. 13 Wniosek Niech • E ⊇ A podzbiór zbioru kraw¦dzi pewnego MST dla G, • C = spójna skªadowa w lesie T = (V, A), • {u, v} kraw¦d¹ o najmniejszej wadze spo±ród ª¡cz¡cych C z pewn¡ inn¡ skªadow¡ w T . Wówczas kraw¦d¹ {u, v} jest bezpieczna dla A. Dowód. Przekrój (C, V \ C) uwzgl¦dnia A. {u, v} jest kraw¦dzi¡ lekk¡ krzy»uj¡c¡ si¦ z tym przekrojem. Na mocy twierdzenia {u, v} jest kraw¦dzi¡ bezpieczn¡ dla A. 4.3 Algorytm Podsumowanie: szczegóªowa wersja algorytmu GenericMST algorytm Kruskala (który jest w pewnym sensie modykacj¡ procedury ConnectedComponents z 3.2). MST-Kruskal(G, w) 1 begin ∅; 2 A := 3 for ka»dy v 4 posortuj 6 for ka»da 7 niemalej¡co wzgl¦dem wag w; {u, v} ∈ E, w kolejno±ci niemalej¡cych wag E begin 9 A := A 10 ∪ { {u, v} }; Union(u, v) 11 end return A end; Zªo»ono±¢: O(|E| · log|E|) (przy najszybszych implementacjach zbiorów rozª¡cznych i sor- towania, por. Twierdzenie 3.5). 4.4 do if FindSet(u) <> FindSet(v) then 8 13 V do MakeSet(v); 5 12 ∈ Przebieg algorytmu Kruskala v 2 f f v @ 1 @ 15 2 @ f v @v f 13 v 2 f f v @ 1 @ 15 2 @ f v @v f 13 f v 9 10 8 f v f v 9 10 8 f v 14 v 2 f f v @ 1 @ 15 2 @ @v f v f 13 v 2 f f v @ 1 @ 15 2 @ @v f v f 13 v 2 f f v @ 1 @ 15 2 @ @v f v f 13 v 2 f f v @ 1 @ 15 2 @ f v @v f 13 v 2 f f v @ 1 @ 15 2 @ f v @v f 13 v f 2 f v @ 1 @ 15 2 @ v f @v f 13 v f 2 f v @ 1 @ 15 2 @ v f @v f 13 v f 2 f v @ 1 @ 15 2 @ v f @v f 13 f v 9 10 8 f v f v 9 10 8 f v f v 9 10 8 f v f v 9 10 8 f v f v 9 10 8 f v f v 9 10 8 f v f v 9 10 8 f v f v 9 10 8 f v 15 5 Prim 5.1 Poprawno±¢ Inna realizacja ogólnego algorytmu GenericMST algorytm Prima • W przeciwie«stwie do algorytmu Kruskala, kraw¦dzie z A tworz¡ zawsze pojedyncze drzewo. • Pocz¡tkowo drzewo to skªada si¦ z dowolnie wybranego wierzchoªkanast¦pnie ro±nie do chwili, w której rozpina wszystkie wierzchoªki z • • (V (A), V \ V (A)) A). Rozwa»any przekrój: (V (A) := korzenia r ∈ V ; V. zbiór ko«ców kraw¦dzi z W ka»dym kroku dodajemy kraw¦d¹ lekk¡ krzy»uj¡c¡ si¦ z tym przekrojem (tj. kraw¦d¹ o najmniejszej wadze spo±ród tych wystaj¡cych z Przekrój (V (A), V \ V (A)) uwzgl¦dnia A, A). zatem kraw¦d¹ ta jest bezpieczna dla A (patrz Twierdzenie 4.2). 5.2 Implementacja Jak wyznacza¢ kraw¦d¹ lekk¡ krzy»uj¡c¡ si¦ z przekrojem • (V (A), V \ V (A))? Wierzchoªki spoza rozrastaj¡cego si¦ drzewa trzymamy w kolejce priorytetowej Q (por. poprzedni wykªad). • Dla ka»dego Q) • v∈V kluczem klucz(v) (tzn. priorytetem wyznaczaj¡cym pozycj¦ w kolejce jest najmniejsza waga spo±ród wag kraw¦dzi ª¡cz¡cych W zmiennej π[v] pami¦tamy ojca Podczas wykonywania algorytmu zbiór v A v z wierzchoªkami drzewa. w obliczanym drzewie. jest pami¦tany niejawnie jako A = { {π[v], v} : v ∈ (V \ {r}) \ Q}. Po zako«czeniu algorytmu Q = ∅, zbiorem kraw¦dzi MST w G jest wi¦c A = { {π[v], v} : v ∈ V \ {r}}. Przypomnijmy, »e symbolem 5.3 Adj[u] oznaczamy zbiór s¡siadów wierzchoªka Algorytm Inna realizacja ogólnego algorytmu algorytm Prima. u. 16 MST-Prim(G, w, r) 1 begin 2 Q := V; ∈ 3 for ka»dy u 4 klucz(r) := 0; 5 π [r] 6 while Q <> 7 := Q do klucz(u) := ∞; ∅ do begin 8 u := ExtractMin(Q); 9 for ka»dy v 10 if (v 11 ∈ ∈ Adj[u] do Q) and (w(u, v) < klucz(v)) then begin π [v] 12 13 := u; klucz[v] := w(u, v) 14 end 15 end; 16 return 17 ∞; π end; Zªo»ono±¢: O(|E| · log|V |) (gdy kolejka implementowana na kopcu). 5.4 Przebieg algorytmu Prima Dowolnie ustalamy korze« r - wierzchoªek startowy. v 2 f f v @ 1 @ 15 2 @ f v f @v 13 2 v f @ @ 15 2 f v 1 @ 13 2 v f @ @ 15 2 f v 13 2 v f @ @ 15 f v 13 2 v f @ @ 15 f v v f @ @ 15 f v @v f f v @v f f v 1 @ 13 2 2 f v 1 @ 2 f @v 1 @ 2 f v @v f f v 1 @ 13 @v f f v r 8 9 10 f v f v r 8 9 10 f v f v r 8 9 10 f v f v r 8 9 10 f v f v r 8 9 10 f v f v r 9 10 8 f v