Algorytm Prima

Ten artykuł od 2014-06 zawiera treści, przy których brakuje odnośników do źródeł.
Należy dodać przypisy do treści niemających odnośników do źródeł. Dodanie listy źródeł bibliograficznych jest problematyczne, ponieważ nie wiadomo, które treści one uźródławiają.
Sprawdź w źródłach: Encyklopedia PWN • Google Books • Google Scholar • Federacja Bibliotek Cyfrowych • BazHum • BazTech • RCIN • Internet Archive (texts / inlibrary)
Dokładniejsze informacje o tym, co należy poprawić, być może znajdują się w dyskusji tego artykułu.
Po wyeliminowaniu niedoskonałości należy usunąć szablon {{Dopracować}} z tego artykułu.
Algorytm Prima
Rodzaj

Wyznaczanie minimalnego drzewa rozpinającego

Struktura danych

graf

Złożoność
Czasowa

O ( | E | log | V | ) {\displaystyle O(|E|\cdot \log |V|)}
O ( | E | + | V | log | V | ) {\displaystyle O(|E|+|V|\cdot \log |V|)} – przy zastosowaniu kopca Fibonacciego

Algorytm Prima – algorytm 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[3], a następnie odkryty na nowo przez informatyka Roberta C. Prima w 1957 oraz niezależnie przez Edsgera Dijkstrę w 1959[4]. Z tego powodu algorytm nazywany jest również czasami algorytmem Dijkstry-Prima, algorytmem DJP, algorytmem Jarníka, albo algorytmem Prima-Jarníka[5].

Algorytm

Schemat działania[6]:

  • 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 | log | V | ) {\displaystyle O(|E|\cdot \log |V|)} [6].
  • Przy zastosowaniu kopca Fibonacciego O ( | E | + | V | log | V | ) , {\displaystyle O(|E|+|V|\cdot \log |V|),} co przy dużej gęstości grafu (takiej, że | E | {\displaystyle |E|} jest ω ( | V | log | V | ) {\displaystyle \omega (|V|\cdot \log |V|)} ) oznacza duże przyspieszenie[7].

Dowód poprawności

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 {\displaystyle n} algorytmu Prima istnieje minimalne drzewo rozpinające Y n {\displaystyle Y_{n}} zawierające drzewo G n {\displaystyle G_{n}} powstałe w kroku algorytmu.

W kroku pierwszym do drzewa G 1 {\displaystyle G_{1}} dodawany jest dowolny wierzchołek v . {\displaystyle v.} Ponieważ każde drzewo rozpinające zawiera wszystkie wierzchołki, jako Y 1 {\displaystyle Y_{1}} możemy wybrać dowolne minimalne drzewo rozpinające.

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

Łatwo zaważyć, że graf G n {\displaystyle G_{n}} dla n = | V | {\displaystyle n=|V|} jest minimalnym drzewem rozpinającym.

Zobacz też

Przypisy

  1. Cormen i in. 2007 ↓, s. 570.
  2. Cormen i in. 2007 ↓, s. 571.
  3. VojtěchV. Jarník VojtěchV., O jistém problému minimálním, „Práce Moravské Přírodovědecké Společnosti”, 6, 1930, s. 57–63  (cz.).
  4. Sysło, Deo i Kowalik 1995 ↓, s. 212.
  5. ŁukaszŁ. Jeleń ŁukaszŁ., Projektowanie algorytmów i metody sztucznej inteligencji. Tablice haszujące, grafy. [online], IIAR PWR, s. 13 [dostęp 2016-03-19] [zarchiwizowane z adresu 2016-03-27] .
  6. a b Cormen i in. 2007 ↓, s. 573.
  7. Cormen i in. 2007 ↓, s. 574.

Bibliografia

  • Thomas H.T.H. Cormen Thomas H.T.H. i inni, Wprowadzenie do algorytmów, WNT, 2007 .
  • PiotrP. Stańczyk PiotrP., Algorytmika Praktyczna w Konkursach Informatycznych [online], styczeń 2007 .
  • Maciej MarekM.M. Sysło Maciej MarekM.M., NarsinghN. Deo NarsinghN., Janusz S.J.S. Kowalik Janusz S.J.S., Algorytmy optymalizacji dyskretnej, wyd. drugie, Warszawa: Wydawnictwo Naukowe PWN, 1995, ISBN 83-01-11818-0 .
  • Opis i implementacja algorytmu Prima [online] [dostęp 2014-07-05] .

Linki zewnętrzne

  • Prim’s algorithm code (Internet Archive). algorithm-code.com. [zarchiwizowane z tego adresu (2009-04-25)].
  • Implementacja C++ łącznie z komentarzem