Wyznaczanie minimalnego drzewa rozpinającego. Algorytm Kruskala

Transkrypt

Wyznaczanie minimalnego drzewa rozpinającego. Algorytm Kruskala
Wyznaczanie minimalnego drzewa rozpinającego.
Algorytm Kruskala
Michał Kasiński
19 marca 2013
Drzewa rozpinające
Definicja 1. Drzewem rozpinającym T spójnego grafu G = (V, E) nazywamy
drzewo takie, że V (T ) = V oraz E(T ) ⊆ E.
Przykład 1. Graf i dwa z jego rozpinających drzew
Fakt 1. Każdy graf spójny zawiera co najmniej jedno drzewo rozpinające.
Definicja 2. Niech T będzie zbiorem wszystkich drzew rozpinających w grafie
ważonym G = (V, E, w). Drzewo T ∈ T , dla którego wartość:
X
w(e)
e∈E(T )
jest najmniejsza nazywamy minimalnym drzewem rozpinającym.
Przykład 2. Graf i jego minimalne drzewo rozpinające
1
Algorytm Kruskala
Jeden z popularnych algorytmów wyznaczania minimalnego drzewa rozpinającego został opracowany przez Josepha Kruskala. W tej metodzie wszystkie
krawędzie są porządkowane według ich wag, następnie algorytm analizuje każdą
z krawędzi tej uporządkowanej sekwencji, sprawdzając, czy może się ona stać
częścią tworzonego drzewa. Krawędź jest dodawana do drzewa, jesli jej dołączenie nie spowoduje powstania żadnego cyklu. Ten prosty algorytm można opisać
w następujący sposób:
A ← ∅;
for każdy wierzchołek v ∈ V (G) do
M AKE − SET (v);
end
posortuj krawędzie z E niemalejąco względem wag w;
for każda krawędź(u, v) ∈ E, w kolejności niemalejących wag do
if F IN D(u)! = F IN D(v) then
A ← A ∪ {(u, v)};
U N ION (u, v);
end
end
return A;
Algorytm 1: Algorytm Kruskala
Przy implementacji algorytmu Kruskala korzystamy ze struktury zbiorów rozłącznych, zwanej lasem zbiorów rozłącznych - każdy zbiór interpretujemy jako
drzewo, stąd określenie lasu. Poświęćmy chwilę na analizę budowy i złożoności
takich struktur.
2
Algorytmy Union-Find
Analiza problemu
• Obiekty.
0123456789
• Zbiory rozłączne.
{0} {1} {2 3 4} {5 6} {7} {8 9}
• Zapytanie FIND: Czy obiekty 2 i 9 należą do tego samego zbioru?
{0} {1} {2 3 4} {5 6} {7} {8 9}
• Operacja UNION: Scal zbiory zawierające elementy 3 i 8
{0} {1} {2 3 4 8 9} {5 6} {7}
Cel: Zaprojektować efektywną strukturę danych dla operacji Union-Find
• Zapytania FIND i UNION mogą następować w losowej kolejności.
• Liczba operacji M może być duża.
• Liczba obiektów N może być duża.
Quick Find (QF) - podejście zachłanne
Struktura danych
Tablica liczb całkowitych id[] rozmiaru N.Gdy p i q są połączone mają taką
samą wartość id.
i
id[i]
0
0
1
1
2
9
3
9
4
9
5
6
6
6
7
7
8
8
9
9
5 i 6 są połączone
2,3,4 i 9 są połączone
FIND - sprawdź czy p i q mają taką samą wartość id.
UNION - zamień wszystkie wystąpienia id[p] na id[q].
i
id[i]
0
0
1
1
2
6
3
6
4
6
UNION(3,6) - 2,3,4,5,6 i 9 są połączone
Uwaga! Zmieniamy dużo wartości.
3
5
6
6
6
7
7
8
8
9
6
Quick Union (QU) - podejście leniwe
Struktura danych
Tablica liczb całkowitych id[] rozmiaru N. id[i] jest rodzicem i. Korzeniem
obiektu i jest id[id[id[...id[i]...]]] (kontynuuj aż do id[i]==i)
0
0
i
id[i]
1
1
2
9
3
4
4
9
5
6
6
6
7
7
8
8
9
9
korzeniem dla 3 jest 9;korzeniem dla 5 jest 6
3 i 5 nie są połączone
FIND - sprawdź czy p i q mają taki sam korzeń.
UNION - zamień id korzenia obiektu q na id korzenia obiektu p.
0
0
i
id[i]
1
1
2
9
3
4
4
9
5
6
6
9
7
7
8
8
9
9
UNION(3,5)
Uwaga! Zmieniła się tylko jedna wartość.
Quick Union jest zbyt wolny
Problemy z Quick Find:
• Operacja UNION zbyt kosztowna (N kroków).
• Drzewa są płaskie, ale zbyt duży koszt utrzymania ich w takiej postaci.
Problemy z Quick Union:
• Drzewa mogą być zbyt wysokie.
• Zapytania FIND są zbyt kosztowne (może być N kroków).
• Trzeba wykonać FIND aby wykonać UNION.
Struktura UNION FIND
QF
N
1
QU
N∗
N
∗
uwzględniając koszt FIND
4
Ulepszenie 1: ważenie (WQU)
Weighted Quick-Union
• Modyfikacja Quick-Union aby zapobiec wysokim drzewom.
• Zapamiętanie rozmiaru każdego zbioru.
• Utrzymanie zbalansowanego drzewa poprzez dołączanie mniejszych drzew
do większych.
Przykład 3.
UNION(5,3)
• Quick-Union: dołącz 9 do 6.
• Ważony Quick-Union: dołącz 6 do 9.
Implementacja
• Prawie identyczna jak Quick-Union
• Dodatkowa tablica sz[] dla liczby elementów w poddrzewie o korzeniu i.
FIND - tak samo jak w QU
UNION - porównanie rozmiarów, aktualizacja wagi
Analiza
• FIND: czas proporcjonalny do głębokości p i q.
• UNION: złożoność obliczeniowa stała przy danych korzeniach.
• Fakt: głębokość conajwyżej log2 N
5
Struktura UNION FIND
QF
N
1
QU
N∗
N
WQU
log2 N ∗ log2 N
∗
uwzględniając koszt FIND
Ulepszenie 2: kompresja ścieżek(WQUPC)
Przy szukaniu korzenia dla i ustawmy obiekty tak, by każdy mijany przez nas
obiekt wskazywał na swojego dziadka. Wystarczy zmienić jedną linijkę w kodzie:
public int r o o t ( int i ) {
while ( i != i d [ i ] ) {
id[i] = id[id[i]] ;
i=i d [ i ] ;
}
return i ;
}
Podsumowanie
Dla M operacji Union-Find na zbiorze N obiektów mamy:
Algorytm
Quick-Find
Quick-Union
Ważony QU
Kompresja ścieżki
Ważony QU + PC
Złożoność pesymistyczna
MN
MN
N + M log2 N
N + M log2 N
(M + N )lg ∗ N
lg ∗ N czyli logarytm iterowany to funkcja o wartości mówiącej ile razy trzeba
wykonać log2 na liczbie N aż do uzyskania 1. W praktyce jest to bardzo wolno
rosnąca funkcja.
lg ∗ N
0
1
2
3
4
5
N
1
2
4
16
65536
265536
Tarjan pokazał, że złożoność jest w jeszcze niższa. Odpowiada funkcji odwrotnej
do funckji Ackermanna. Dowód przekracza moje kompetencje.
6
Złożoność
Dzięki zastosowaniu algorytmu WQUPC oraz mając posortowane krawędzie algorytm Kruskala osiąga złożoność obliczeniową O(|E|lg ∗ |V |).
Zastosowania
Algorytm Kruskala znajduje zastosowanie tam, gdzie znajdują zastosowanie minimalne drzewa rozpinające, m.in. w:
• Taksonomii
• Segmentacji obrazów
• Sieciach komputerowych (protokół STP)
• Rozpoznawaniu (pisma) wyrażeń matematycznych
• Projektowaniu obwodów
7