Algorytm Prima

Z Wikipedii, wolnej encyklopedii
Skocz do: nawigacja, szukaj
Algorytm Prima
Rodzaj Wyznaczanie minimalnego drzewa rozpinającego
Struktura danych graf
Złożoność
Czasowa O(E \cdot \log V)

O(E + V \cdot \log V) - przy zastosowaniu kopca Fibonacciego

Niniejszy artykuł jest częścią cyklu teoria grafów.




Najważniejsze pojęcia
graf
drzewo
podgraf
cykl
klika
stopień wierzchołka
stopień grafu
dopełnienie grafu
obwód grafu
pokrycie wierzchołkowe
liczba chromatyczna
indeks chromatyczny
izomorfizm grafów
homeomorfizm grafów


Wybrane klasy grafów
graf pełny
graf spójny
drzewo
graf dwudzielny
graf regularny
graf eulerowski
graf hamiltonowski
graf planarny


Algorytmy grafowe
A*
Bellmana-Forda
Dijkstry
Fleury'ego
Floyda-Warshalla
Johnsona
Kruskala
Prima
przeszukiwanie grafu
wszerz
w głąb
najbliższego sąsiada


Zagadnienia przedstawiane jako problemy grafowe
problem komiwojażera
problem chińskiego listonosza
problem marszrutyzacji
problem kojarzenia małżeństw


Inne zagadnienia
kod Graya
diagram Hassego
kod Prüfera


Algorytm Primaalgorytm zachłanny wyznaczający tzw. minimalne drzewo rozpinające (MDR)[1]. Mając do dyspozycji graf nieskierowany i spójny, tzn. taki w którym krawędzie grafu nie mają ustalonego kierunku oraz dla każdych dwóch wierzchołków grafu istnieje droga pomiędzy nimi, algorytm oblicza podzbiór E' zbioru krawędzi E, dla którego graf nadal pozostaje spójny, ale suma kosztów wszystkich krawędzi zbioru E' jest najmniejsza możliwa[2].

Algorytm został wynaleziony w 1930 przez czeskiego matematyka Vojtěcha Jarníka, a następnie odkryty na nowo przez informatyka Roberta C. Prima w 1957 oraz niezależnie przez Edsgera Dijkstrę w 1959[potrzebny przypis]. Z tego powodu algorytm nazywany jest również czasami algorytmem Dijkstry–Prima, algorytmem DJP, algorytmem Jarníka, albo algorytmem Prima–Jarníka[3].

Algorytm[edytuj]

Schemat działania[4]:

  • Utwórz drzewo zawierające jeden wierzchołek, dowolnie wybrany z grafu.
  • Utwórz kolejkę priorytetową, zawierającą wierzchołki osiągalne z MDR (w tym momencie zawiera jeden wierzchołek, więc na początku w kolejce będą sąsiedzi początkowego wierzchołka), o priorytecie najmniejszego kosztu dotarcia do danego wierzchołka z MDR.
  • Powtarzaj, dopóki drzewo nie obejmuje wszystkich wierzchołków grafu:
    • wśród nieprzetworzonych wierzchołków (spoza obecnego MDR) wybierz ten, dla którego koszt dojścia z obecnego MDR jest najmniejszy.
    • dodaj do obecnego MDR wierzchołek i krawędź realizującą najmniejszy koszt
    • zaktualizuj kolejkę priorytetową, uwzględniając nowe krawędzie wychodzące z dodanego wierzchołka

Złożoność obliczeniowa w zależności od implementacji kolejki priorytetowej:

  • Dla wersji opartej na zwykłym kopcu (bądź drzewie czerwono-czarnym) O(E \cdot \log V)[4].
  • Przy zastosowaniu kopca Fibonacciego O(E + V \cdot \log V), co przy dużej gęstości grafu (takiej, że E jest \omega(V \cdot \log V) oznacza duże przyspieszenie[5].

Dowód poprawności[edytuj]

Weźmy dowolny spójny graf nieskierowany z wagami. Wiemy, że istnieje co najmniej jedno minimalne drzewo rozpinające. Udowodnimy, że dla każdego kroku n algorytmu Prima istnieje minimalne drzewo rozpinające Y_n zawierające drzewo G_n powstałe w kroku algorytmu.

W kroku pierwszym do drzewa G_1 dodawany jest dowolny wierzchołek v. Ponieważ każde drzewo rozpinające zawiera wszystkie wierzchołki, jako Y_1 możemy wybrać dowolne minimalne drzewo rozpinające.

Dla dowolnego kroku n, gdzie n > 1, wiemy, że graf G_{n-1} zawiera się w pewnym minimalnym drzewie rozpinającym Y_{n-1}. W kroku wybierana jest krawędź e, łącząca wierzchołek v_e należący do grafu G_{n-1} z wierzchołkiem v_e' nienależącym do grafu G_{n-1}. Jeżeli krawędź e należy do Y_{n-1}, to możemy przyjąć Y_n = Y_{n-1}. W przeciwnym wypadku, w drzewie Y_{n-1} musi istnieć inna ścieżka łącząca wierzchołki v_e i v_e'. Ścieżka taka musi zawierać pewną krawędź f łączącą pewien wierzchołęk v_f należący do grafu G_{n-1} z pewnym wierzchołkiem v_f' do grafu G_{n-1} nienależącym. Weźmy wtedy graf Y_n powstały przez usunięcie z grafu Y_{n-1} krawędzi f i dodanie krawędzi e. Krawędź e ma wagę mniejszą lub równą wadze krawędzi f. W przeciwnym wypadku krawędź e nie mogłaby być wybrana przez algorytm. Wnioskujemy, że suma wag krawędzi grafu Y_n jest nie większa od sumy wag krawędzi grafu Y_{n-1}. Udowodnijmy jeszcze, że graf Y_n jest drzewem rozpinającym. Dla dowolnych dwóch wierzchołków istnieje w drzewie Y_{n-1} ścieżka je łącząca. Jeżeli ścieżka ta nie zawierała krawędzi f to zawiera się ona też w grafie Y_n. Jeżeli ścieżka ta zawiera krawędź f, to można ją zastąpić ścieżką łączącą wierzchołki v_f z v_e, krawędzią e i ścieżką łączącą wierzchołki v_e' z v_f'.

Łatwo zaważyć, że graf G_n dla n = V jest minimalnym drzewem rozpinającym.

Zobacz też[edytuj]

Przypisy

Bibliografia[edytuj]

Linki zewnętrzne[edytuj]