Algorytm Dijkstry

Algorytm Dijkstry
Ilustracja
Ilustracja działania algorytmu
Rodzaj

Znajdowanie najkrótszej ścieżki

Struktura danych

graf

Złożoność
Czasowa

Pamięciowa

- przy użyciu 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 Dijkstry, opracowany przez holenderskiego informatyka Edsgera Dijkstrę, służy do znajdowania najkrótszej ścieżki z pojedynczego źródła w grafie o nieujemnych wagach krawędzi.

Działanie

Mając dany graf z wyróżnionym wierzchołkiem (źródłem) algorytm znajduje odległości od źródła do wszystkich pozostałych wierzchołków. Łatwo zmodyfikować go tak, aby szukał wyłącznie (najkrótszej) ścieżki do jednego ustalonego wierzchołka, po prostu przerywając działanie w momencie dojścia do wierzchołka docelowego, bądź transponując tablicę incydencji grafu.

Algorytm Dijkstry znajduje w grafie wszystkie najkrótsze ścieżki pomiędzy wybranym wierzchołkiem a wszystkimi pozostałymi, przy okazji wyliczając również koszt przejścia każdej z tych ścieżek[1].

Algorytm Dijkstry jest przykładem algorytmu zachłannego[2].

Algorytm

Przez oznaczamy wierzchołek źródłowy, to waga krawędzi w grafie.

  • Stwórz tablicę odległości od źródła dla wszystkich wierzchołków grafu. Na początku zaś dla wszystkich pozostałych wierzchołków.
  • Utwórz kolejkę priorytetową wszystkich wierzchołków grafu. Priorytetem kolejki jest aktualnie wyliczona odległość od wierzchołka źródłowego
  • Dopóki kolejka nie jest pusta:
    • Usuń z kolejki wierzchołek o najniższym priorytecie (wierzchołek najbliższy źródła, który nie został jeszcze rozważony)
    • Dla każdego sąsiada wierzchołka dokonaj relaksacji poprzez jeśli (poprzez da się dojść do szybciej niż dotychczasową ścieżką), to

Na końcu tablica zawiera najkrótsze odległości do wszystkich wierzchołków.

Dodatkowo możemy w tablicy poprzednik przechowywać dla każdego wierzchołka numer jego bezpośredniego poprzednika na najkrótszej ścieżce, co pozwoli na odtworzenie pełnej ścieżki od źródła do każdego wierzchołka – przy każdej relaksacji w ostatnim punkcie staje się poprzednikiem

Zastosowanie

Z algorytmu Dijkstry można skorzystać przy obliczaniu najkrótszej drogi do danej miejscowości. Wystarczy przyjąć, że każdy z punktów skrzyżowań dróg to jeden z wierzchołków grafu, a odległości między punktami to wagi krawędzi.

Jest często używany w sieciach komputerowych, np. przy trasowaniu (przykładowo w protokole OSPF).

Pseudokod

Dijkstra(G,w,s):
   dla każdego wierzchołka v w V[G] wykonaj
      d[v] := nieskończoność
      poprzednik[v] := niezdefiniowane
   d[s] := 0
   Q := V
   dopóki Q niepuste wykonaj
      u := Zdejmij_Min(Q)
      dla każdego wierzchołka v – sąsiada u wykonaj
         jeżeli d[v] > d[u] + w(u, v) to
            d[v] := d[u] + w(u, v)
            poprzednik[v] := u

   Wyświetl("Droga wynosi: " + d[v])

Dowód poprawności

Oznaczmy przez zbiór wierzchołków, które zostały już zdjęte z kolejki. Dowód opiera się na następujących dwóch faktach (niezmiennikach), prawdziwych przez cały czas trwania algorytmu:

  1. Dla każdego wierzchołka liczba jest długością najkrótszej ścieżki od do
  2. Dla każdego wierzchołka jest długością najkrótszej ścieżki do prowadzącej tylko przez wierzchołki z

Na początku oba fakty są oczywiste ( jest zbiorem pustym). Przy zdejmowaniu wierzchołka z kolejki wiemy, na podstawie faktu 2, że nie da się do niego dojść żadną krótszą drogą przez wierzchołki z Z drugiej strony, ponieważ ma najniższy priorytet, przejście przez jakikolwiek inny wierzchołek spoza dałoby od razu co najmniej tak samo długą ścieżkę. A zatem dołączając wierzchołek do zachowujemy prawdziwość faktu 1. Następnie musimy uwzględnić fakt, że najkrótsza ścieżka do jakiegoś wierzchołka po wierzchołkach z nowego zbioru może teraz zawierać wierzchołek Ale wtedy musi on być ostatnim na niej wierzchołkiem (do każdego innego dałoby się dojść krócej, nie używając ), a zatem jej długość równa jest i zostanie prawidłowo obliczona w następnym kroku algorytmu.

Złożoność

Złożoność obliczeniowa algorytmu Dijkstry zależy od liczby wierzchołków i krawędzi grafu. O rzędzie złożoności decyduje implementacja kolejki priorytetowej:

  • wykorzystując „naiwną” implementację poprzez zwykłą tablicę, otrzymujemy algorytm o złożoności
  • w implementacji kolejki poprzez kopiec, złożoność wynosi
  • po zastąpieniu zwykłego kopca kopcem Fibonacciego złożoność zmienia się na

Pierwszy wariant jest optymalny dla grafów gęstych (czyli jeśli ), drugi jest szybszy dla grafów rzadkich trzeci jest bardzo rzadko używany ze względu na duży stopień skomplikowania i niewielki w porównaniu z nim zysk czasowy.

Problemy i algorytmy pokrewne

Algorytm Dijkstry nie działa, jeśli w grafie występują krawędzie z ujemnymi wagami – w tym wypadku używa się wolniejszego, lecz bardziej ogólnego algorytmu Bellmana-Forda. Jeśli graf nie jest ważony (wszystkie wagi mają wielkość 1), zamiast algorytmu Dijkstry wystarczy algorytm przeszukiwania grafu wszerz.

Algorytm A* jest pewnym uogólnieniem algorytmu Dijkstry, które pozwala przeszukiwać tylko część grafu, jednak wymaga dodatkowej wstępnej informacji (heurystyki) o odległościach wierzchołków.

Algorytm Prima znajdowania minimalnego drzewa rozpinającego oparty jest o bardzo podobny pomysł co algorytm Dijkstry.

Przypisy

  1. Algorytm Dijkstry. edu.i-lo.tarnow.pl. [zarchiwizowane z tego adresu (2009-01-25)]..
  2. Algorytm Dijkstry.

Bibliografia

Linki zewnętrzne

Media użyte na tej stronie

Dijkstra Animation.gif
Animation, describing Dijkstra's algorithm runtime.