|
|||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||
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. Jest często używany w routingu. 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 ścieżki do jednego ustalonego wierzchołka, po prostu przerywając działanie w momencie dojścia do wierzchołka docelowego. Algorytm Dijkstry jest przykładem algorytmu zachłannego.
edytuj AlgorytmPrzez s oznaczamy wierzchołek źródłowy, w(i,j) to waga krawędzi (i,j) w grafie.
Na końcu tablica d 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, u staje się poprzednikiem v. edytuj 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
edytuj Dowód poprawnościOznaczmy przez S 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:
Na początku oba fakty są oczywiste (S jest zbiorem pustym). Przy zdejmowaniu wierzchołka u z kolejki wiemy, na podstawie faktu 2, że nie da się do niego dojść żadną krótszą drogą przez wierzchołki z S. Z drugiej strony, ponieważ u ma najniższy priorytet, przejście przez jakikolwiek inny wierzchołek spoza S dałoby od razu co najmniej tak samo długą ścieżkę. A zatem dołączając wierzchołek u do S zachowujemy prawdziwość faktu 1. Następnie musimy uwzględnić fakt, że najkrótsza ścieżka do jakiegoś wierzchołka v po wierzchołkach z nowego zbioru S może teraz zawierać wierzchołek u. Ale wtedy musi on być ostatnim na niej wierzchołkiem (do każdego innego dałoby się dojśc krócej nie używając u), a zatem jej długość równa jest du + w(u,v) i zostanie prawidłowo obliczona w następnym kroku algorytmu. edytuj ZłożonośćZłożoność obliczeniowa algorytmu Dijkstry zależy od liczby V wierzchołków i E krawędzi grafu. O rzędzie złożoności decyduje implementacja kolejki priorytetowej:
Pierwszy wariant jest optymalny dla grafów gęstych (czyli jeśli E = Θ(V2)), drugi jest szybszy dla grafów rzadkich (E = Θ(V)), trzeci jest bardzo rzadko używany ze względu na duży stopień skomplikowania i niewielki w porównaniu z nim zysk czasowy. edytuj Problemy i algorytmy pokrewneAlgorytm 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. edytuj Zobacz teżedytuj Bibliografia
edytuj Linki zewnętrzne |
| All Right Reserved © 2007, Designed by Stylish Blog. |