Szukanie najkrótszych dróg z jednym ródłem
Algorytm Dijkstry Załoenia: dany jest spójny graf prosty G z wagami na krawdziach waga w(e) dla kadej krawdzi e jest nieujemna dany jest wyróniony wierzchołek s Wyjcie: dla kadego wierzchołka v algorytm znajduje d[v], długo najkrótszej drogi z wierzchołka s do v. Przez długo drogi rozumiemy sum wag krawdzi nalecych do drogi. Uwaga: Algorytm mona łatwo zmodyfikowa tak, aby oprócz długoci drogi wyznaczał krawdzie do niej nalece oraz tak, aby działał w przypadku grafów skierowanych.
9 Pseudokod Uwaga S jest pomocniczym zbiorem wierzchołków (nazywany zbiorem pewnoci). O wierzchołku v nalecym do S wiadomo, e jego etykieta d[v] jest równa długoci najkrótszej drogi z s do v. Procedure Dijkstra(G, s) begin S := ; d[s] = ; d[ v] = dla v s; for i := to n do begin znajd v V\S, posiadajcy minimaln etykiet d[ v]; S := S {v}; for kady ssiad u V\S do begin d[ u] := min{d[ u], d[ v] + w({u,v}) };
4 Przykład s Procedure Dijkstra(G, s) begin S := ; d[s] = ; d[ v] = dla v s; for i := to n do begin znajd v V\S, o minimalnym d[ v]; S := S {v}; for kady ssiad u V\S do begin d[ u] := min{d[ u], d[ v] + w({u,v}) }; 4 4 2 4 2 9 2 2 Szukamy długoci najkrótszej drogi z s do t. Elementy zbioru S oznaczamy kolorem czerwonym. Odpowied: najkrótsza droga z s do t ma długo. 4 t 5
4 Uwagi o implementacji operacje znajd v V\S, o minimalnym d[ v]; S := S {v}; s wykonywane O(n) razy operacja d[ u] := min{d[ u], d[ v] + w({u,v}) }; jest wykonywana O(m) razy do wydajnej implementacji wykorzystujemy kopiec binarny o tej własnoci, e klucz zapamitany w danym wle jest mniejszy od kluczy jego synów elementami kopca s wierzchołki V\S, a klucze to liczby d[v] w ogólnym przypadku czas budowy kopca to O(nlogn), lecz w algorytmie Dijkstry (wykorzystujc fakt, e inicjalnie wszystkie klucze, z wyjtkiem d[s] s identyczne) czas ten jest liniowy wyszukiwanie wierzchołka w zbiorze V\S o minimalnym kluczu, dziki własnoci kopca, moe by wykonana w czasie stałym usunicie elementu o minimalnym kluczu (czyli instrukcja S := S {v}; ) wymaga czasu O(log( V\S )) = O(logn) operacja d[ u] := min{d[ u], d[ v] + w({u,v}) }; wymaga czasu O(log( V\S )) ostatecznie, czas działania algorytmu Dijkstry to O((n+m)logn)
42 Algorytm Bellmana-Forda Wejcie: obciony spójny digraf G. Dozwolone ujemne wagi na krawdziach. Algorytm stwierdza czy istnieje cykl o ujemnej sumie wag. Jeli taki cykl istnieje, to algorytm zwraca informacj o błdzie Jeli powyszego cyklu nie ma, to algorytm znajduje długoci najkrótszych dróg ze ródła s do wszystkich pozostałych wierzchołków grafu
4 Szkic algorytmu algorytm szuka długoci najkrótszych dróg z wyrónionego wierzchołka s do wszystkich pozostałych wierzchołków grafu długo znalezionej drogi z s do v jest zapamitana jako d[v] inicjalnie d[s] = oraz d[v] = dla s v główna ptla algorytmu jest wykonywana n razy kady przebieg głównej ptli polega na wykonaniu relaksacji kadej krawdzi relaksacja krawdzi (u,v) jest zmniejszeniem oszacowania d[v] jeli warto dotychczas zapamitana jest wiksza ni d[u] + w((u,v)), gdzie w((u,v)) to waga krawdzi (u,v) po zakoczeniu oblicze w głównej ptli algorytmu nastpuje sprawdzenie czy w digrafie istnieje cykl o ujemnej sumie wag, co jest realizowane poprzez sprawdzenie czy mona dokona relaksacji dowolnej krawdzi jeli relaksacja jest moliwa, to graf zawiera cykl o ujemnej sumie wag, co oznacza, e najkrótszych dróg nie mona obliczy jeli relaksacja nie jest moliwa, to zapamitane wartoci d[v] s szukanymi długociami najkrótszych dróg z s
44 Pseudokod procedure Bellman-Ford( G, w, s ) begin d[s] = ; for each v V(G)\{s} do d[v] = + ; for i := to n do for each (u,v) E(G) do if d[u] + w((u,v)) < d[v] then d[v] := d[u] + w((u,v)); for each (u,v) E(G) do if d[u] + w((u,v)) < d[v] then return false; return true;
45 Przykład 2 Rys. : Sytuacja po inicjalizacji. 2 Rys. 2: Sytuacja po wykonaniu ptli dla i = 4 2 Rys. : Sytuacja po wykonaniu ptli dla i = 2 5 4 2 5 Rys. 4: Sytuacja po wykonaniu ptli dla i = 2 5 Rys. 5: Sytuacja po wykonaniu ptli dla i = 4 2 5 Rys. : Sytuacja po wykonaniu ptli dla i = 5
4 Poprawno Tw Jeli digraf G nie posiada ujemnych cykli osigalnych ze ródła s, to po zakoczeniu algorytmu Bellmana-Forda d[v] jest równe długoci najkrótszej cieki z s do v dla kadego wierzchołka v osigalnego z s. Dowód: niech s=v,...,v k =v bdzie najkrótsz ciek z s do v mamy k < V(G) dowodzimy indukcyjnie, e d[v i ] jest równe długoci najkrótszej cieki z s do v i po i-tym przebiegu drugiej ptli for jeli i=, to własno wynika z faktu, e w fazie inicjalizacji algorytmu podstawiamy d[s]= i równo ta nie ulega zmianie podczas działania algorytmu niech i >. Po dokonaniu relaksacji krawdzi (v i-,v i ) w i-tym przebiegu ptli liczba d[v i ] przyjmuje warto najkrótszej cieki z s do v i.
4 Poprawno Tw. Jeli digraf G zawiera cykl o ujemnej wadze osigalny z s, to algorytm Bellmana-Forda zwraca warto false. Dowód: niech v,...,v k =v bdzie cyklem o ujemnej sumie wag, tzn. i=, )) < Gdyby algorytm zwrócił warto true, to dla kadego wierzchołka cyklu mamy d[v i ] d[v i- ] + w((v i-,v i )). Sumujc nierównoci parami otrzymujemy k i= Wartoci pierwszych dwóch sum w powyszym wyraeniu s sobie równe wic co prowadzi do sprzecznoci. i k d[ v ] k i= w(( v i v i k i= w(( d[ v i ] + k i= v i, v i )) w(( v i, v )) i