Najkrótsze drogi w grafach z wagami Autor projektu: dr Andrzej Mróz (UMK) Projekt pn. Wzmocnienie potencjaªu dydaktycznego UMK w Toruniu w dziedzinach matematyczno-przyrodniczych realizowany w ramach Poddziaªania 4.1.1 Programu Operacyjnego Kapitaª Ludzki 1 / 37
Problem Na poprzednim wykªadzie omawiali±my problem znajdowania najkrótszych dróg w grae (algorytm BFS), przy czym najkrótsze drogi oznaczaªy drogi o najmniejszej liczbie kraw dzi. W praktycznych zastosowaniach rzeczywisto± lepiej modeluj grafy, w których kraw dzie maj dªugo± (inaczej koszt = wag ). Na tym wykªadzie zajmiemy si zagadnieniem poszukiwania najkrótszych dróg wzgl dem tego dodatkowego parametru. / 37
Problem Algorytm BFS wykorzystywaª kolejk. Przedstawimy algorytm Dijkstry, który b dzie w pewnym sensie modykacj algorytmu BFS, wykorzystuj c tym razem kolejk priorytetow (ze wzgl du na dodatkowy parametr, wag ). Przedstawimy te» inne podej±cie, algorytm Bellmana-Forda, realizuj cy zbli»one zadanie. Ma on gorsz zªo»ono± ale jest prostszy w implementacji (nie korzysta z kolejki priorytetowej). 3 / 37
Problem Algorytmy te, zwªaszcza algorytm Dijkstry, s w praktyce wykorzystywane w routingu sieciowym, ro»nego rodzaju urz dzeniach nawigacyjnych (jak GPS...), aplikacjach zwi zanych z mapami (jak Google Maps), planowaniu lotów, sieciach telefonicznych, i innych, bardziej specjalistycznych zagadnieniach. Zaczniemy od sformalizowania problemu. 4 / 37
Graf z wagami Denicja Grafem z wagami nazywamy graf (skierowany) G = (V, E) wraz z funkcj wagi w : E R. Uwaga W tej prezentacji ograniczamy si do grafów zorientowanych, algorytmy w wersji niezorientowanej s analogiczne. Zauwa»my,»e w ogólnej denicji na funkcj wagi nie nakªada si»adnych ogranicze«, w szczególno±ci jej warto±ci mog by ujemne. / 37
Przykªad Na rysunku grafu warto±ci funkcji wagi zaznaczamy zazwyczaj przy kraw dziach: 10 1 3 7 10 0 6 4 6 4, Powy»szy diagram przedstawia graf G = (V, E), gdzie V = {1,, 3, 4,, 6}, E = { (1, ), (, 1), (1, ), (1, 4), (4, ), (, ), (, 3), (, 6) }, z funkcj wagi w : E R okre±lon : w(1, ) = 10 w(, 1) = w(1, ) = 10 w(1, 4) = 7 w(4, ) = w(, ) = 0 w(, 3) = 6 w(, 6) = 4,. 6 / 37
Reprezentacje grafu z wagami Ustalmy graf zorientowany G = (V, E) z funkcj wagi w : E R. Najwygodniejsze reprezentacje grafów z wagami to odpowiednie modykacje macierzy s siedztwa lub list s siedztwa. Macierz s siedztwa (wagowa): macierz A = A(G) M n n (Z) o wspóªczynnikach: { 0, (i, j) / E, A i,j = w((i, j)), (i, j) E (analogicznie w wersji niezorientowanej). 7 / 37
Reprezentacje grafu z wagami Przykªad wagowej macierzy s siedztwa. 7 10 1 3 10 0 6 4 6 4, Ai,j 1 3 4 6 1 0 10 0 7 10 0 0 0 0 0 0 3 0 0 0 0 0 0 4 0 0 0 0 0 0 0 6 0 0 4, 6 0 0 0 0 0 0 8 / 37
Reprezentacje grafu z wagami Listy s siedztwa (wagowe): tablica Adj[1..n], gdzie Adj[i] = wska¹nik do listy s siadów i, tj. tych wierzchoªków j,»e (i, j) E. Ka»dy element j listy s siadów wierzchoªka i zawiera dodatkowe pole z wag w(i, j). 9 / 37
Reprezentacje grafu z wagami Przykªad wagowych list s siedztwa. 7 10 1 3 10 0 6 4 6 4, L[i] 1 {; 10} {; 10} {4; 7} {1; } {; 0} 3 4 {; } {3; 6} {6; 4, } 6 10 / 37
Reprezentacje grafu z wagami Lista kraw dzi (wagowa): [ [u 1, v 1, w(u 1, v 1 )], [u, v, w(u, v )],..., [u m, v m, w(u m, v m )] ], gdzie E = { (u i, v i ) : i = 1,..., m }. 11 / 37
Reprezentacje grafu z wagami Przykªad wagowej listy kraw dzi. 7 10 1 3 10 0 6 4 6 4, [ [1,, 10], [, 1, ], [1,, 10], [1, 4, 7], [4,, ], [,, 0], [, 3, 6], [, 6, 4,] ] 1 / 37
Waga drogi Dla dowolnej drogi P = (v 0, v 1,..., v k ) w grae G = (V, E), v i V, deniujemy jej wag jako liczb k w(p) := w((v i 1, v i )). i=1 Czyli rozszerzamy denicj funkcji w z kraw dzi na wszystkie drogi. Przykªad. 10 1 3 7 10 0 6 4 6 4, w((1,,, 3)) = 10 + 0 6 = 4, w((1,, 1, 4)) = 10 + + 7 =, w((1,, 1,,, 6)) = 10 + + 10 + 0 + 4, = 49,. 13 / 37
Najkrótsze drogi w grae z wagami Ustalmy graf G = (V, E) z wagami w : E R. Denicja Waga najkrótszej drogi z u do v, dla u, v V, to liczba { min{w(p) : u P v}, gdy istnieje droga z u do v, δ(u, v) :=, w p.p. u P v oznacza,»e P jest drog z u do v. Uwaga Minimum w denicji nie zawsze istnieje! chwil. Wrócimy do tego za 14 / 37
Najkrótsze drogi w grae z wagami Przykªad. 7 10 1 3 10 0 6 4 6 4, δ(1, ) = 10, δ(1, ) = 9, δ(, ) = 14, δ(1, 6) = 13,. 1 / 37
Problem cykli ujemnych Rozwa»my graf z wagami: 1 3 1 Wówczas w(1,, 3) = 10, w(1,, 3, 1,, 3) = 1, w(1,, 3, 1,, 3, 1,, 3) = 0,... Czyli warto± δ(1, 3) = min{w(p) : u P v} jest nieokre±lona! W takiej sytuacji kªadziemy δ(1, 3) :=. Jest to tzw. problem cykli ujemnych. Algorytm poszukiwania najkrótszych dróg powinien sobie z nim radzi (albo go unikn ). 16 / 37
Warianty problemu najkrótszych dróg 1 Najkrótsze drogi z jednym ¹ródªem. Analogicznie jak BFS dla grafów bez wag z poprzedniego wykªadu. Najkrótsze drogi z jednym wierzchoªkiem docelowym. Ten problem mo»na rozwi za przy pomocy pierwszego. 3 Najkrótsza droga mi dzy par wierzchoªków. Pokazuje si,»e ten problem jest obliczeniowo równowa»ny pierwszemu. Tzn. algorytmy szukaj ce najkrótszej drogi z u do v, jako skutek uboczny i tak musz wyliczy wszystkie najkrótsze drogi z jednym ¹ródªem u. 4 Najkrótsze drogi mi dzy wszystkimi parami wierzchoªków. Ten problem mo»na rozwi za przy pomocy pierwszego (dla wszystkich ¹ródeª). S te» specjalne algorytmy opracowane dla tego konkretnego problemu, np. algorytm Floyda-Warshalla. 17 / 37
Warianty problemu najkrótszych dróg W dalszej cz ±ci wykªadu omówimy dwa ró»ne algorytmy rozwi zuj ce wariant pierwszy, najkrótsze drogi z jednym ¹ródªem: 1 Algorytm Dijkstry. Algorytm Bellmana-Forda. 18 / 37
Oznaczenia i konwencje Ustalmy graf z wagami G = (V, E). Najkrótsze drogi z jednym ¹ródªem s V. π[v] poprzednik wierzchoªka v na tymczasowej najkrótszej drodze z s do v. Dla ka»dego v V trzymamy atrybut d[v] = oszacowanie wagi najkrótszej drogi = górne ograniczenie wagi najkrótszej drogi z s do v. W trakcie algorytmów atrybuty (wektory) te b d modykowane, by mo»e wielokrotnie na tych samych wspóªrz dnych. Warto±ci d[v] b d male. Po zako«czeniu algorytmów: π b dzie zawieraª poprzedników na najkrótszych drogach z s, d b dzie zawieraª wagi najkrótszych dróg z s, tj. d[v] = δ(s, v), dla ka»dego v V. 19 / 37
Oznaczenia i konwencje Poniewa» wykorzystujemy znak jako stra»nika, ustalamy prost arytmetyk na niesko«czono±ciach: Dla a R { }, przyjmujemy a + = + a =. Dla a R { }, przyjmujemy a + ( ) = ( ) + a =. Realizacja tej arytmetyki zale»y od konkretnej implementacji. 0 / 37
Procedura relaksacji Relaksacja (=osªabienie ogranicze«) kraw dzi (u, v) sprawdzenie, czy przechodz c przez u, mo»na znale¹ krótsz od dotychczas najkrótszej drogi do v. Je»eli tak, uaktualniamy warto±ci d[v] i π[v]. Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u 1 / 37
Poprawno± Oba algorytmy polegaj na wykonaniu serii relaksacji w odpowiedniej kolejno±ci. Dowód poprawno±ci obu algorytmów opiera si na nast puj cych prostych faktach (zwi zanych z relaksacj ). Lemat 1 Poddroga najkrótszej drogi te» jest najkrótsz drog. Lemat (Nierówno± trójk ta) Dla ka»dych u, v, x V zachodzi nierówno± : δ(u, v) δ(u, x) + δ(x, v). Peªen dowód pomijamy, mo»na go znale¹ np. w ksi»ce [1] ze spisu literatury do wykªadu (T. H. Cormen et al.). / 37
Inicjalizacja W obu algorytmach wykorzystamy nast puj c inicjalizacj wektorów π i d: Initialize(G, s) for ka»dy v V(G) do d[v] := ; π[v] := d[s] := 0 3 / 37
Specykacja Przypomnijmy,»e przy ujemnych warto±ciach funkcji wagi mog wyst pi ujemne cykle. W przypadku algorytmu Dijkstry po prostu nie dopuszcza si wag ujemnych by unikn problemu. Algorytm Dijkstry. Dane: graf skierowany G = (V, E), nieujemna funkcja wagi w oraz wierzchoªek ¹ródªowy s V. Wynik: dla ka»dego v V osi galnego z s, warto± d[v] = δ(s, v) oraz poprzednik π[v] na najkrótszej drodze z s do v. 4 / 37
Ogólna idea Strategia (zachªanna): S = zbiór wierzchoªków, dla których wagi najkrótszych dróg s policzone, tj. v S d[v] = δ(s, v). powtarzanie nast puj cych operacji: bierzemy u V \ S o najmniejszej warto±ci d[u] ( zbiór V \ S kolejka priorytetowa!); dodajemy u do S i wykonujemy relaksacj na wszystkich kraw dziach u v. Zbiór S i operacje na nim mo»na pomin w implementacji. / 37
Kolejka priorytetowa - przypomnienie Kolejka priorytetowa (typu MIN) = struktura danych K, w której elementy s liniowo uporz dkowane (przy pomocy pewnego klucza, inaczej priorytetu) i przetwarzane w kolejno±ci od obiektu o najni»szym priorytecie do obiektu o najwy»szym priorytecie. Operacja: ExtractMin(K) zwrócenie i usuni cie elementu o najni»szym priorytecie z kolejki K. Uwaga W algorytmie Dijkstry elementami kolejki K b d wierzchoªki, ich priorytetami warto±ci d[v]. 6 / 37
Kolejka priorytetowa - przypomnienie Przypomnijmy,»e kolejk priorytetow najefektywniej implementuje si przy pomocy kopca. Mo»na te» zasymulowa jej dziaªanie na zwykªej tablicy (wtedy operacja ExtractMin polega m.in. na wyszukaniu minimum w tablicy). Mo»na te» u»y gotowych struktur, jak priority_queue biblioteki STL j zyka C++ http://www.cplusplus.com/reference/queue/priority_queue/ 7 / 37
Kolejka priorytetowa - relaksacja Uwaga techniczna: W procedurze relaksacji uaktualniamy warto±ci wektora d (czyli priorytety): Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u Zatem w zale»no±ci od implementacji kolejki priorytetowej nale»y odpowiednio uaktualni struktur kolejki: je»eli kolejka implementowana jest na kopcu, nale»y przywróci wªasno± kopca! 8 / 37
Algorytm Dijkstra(G, w, s) 1 Initialize(G, s); 3 S := ; 4 Q := V(G); while Q <> do 6 7 u := ExtractMin(Q); 8 S := S {u}; 9 for ka»dy v Adj[u] do 10 Relax(u, v, w); 11 1 Najwa»niejsze w dowodzie poprawno±ci: dla ka»dego u dodawanego do S mamy d[u] = δ(s, u). 9 / 37
Algorytm - zªo»ono± Dijkstra(G, w, s) 1 Initialize(G, s); 3 S := ; 4 Q := V(G); while Q <> do 6 7 u := ExtractMin(Q); 8 S := S {u}; 9 for ka»dy v Adj[u] do 10 Relax(u, v, w); 11 1 Zªo»ono± (szkic). Kolejka implementowana na tablicy: ExtractMin na tablicy: O( V ); wiersz 7 wykonany V razy ( skªadnik O( V ) w zªo». caªego algorytmu); dodatkowo wiersz 10 globalnie wykonywany jest O( E ) razy. Zªo»ono± O( V + E ) = O( V ) (bo E = O( V )). 30 / 37
Algorytm - zªo»ono± Dijkstra(G, w, s) 1 Initialize(G, s); 3 S := ; 4 Q := V(G); while Q <> do 6 7 u := ExtractMin(Q); 8 S := S {u}; 9 for ka»dy v Adj[u] do 10 Relax(u, v, w); 11 1 Zªo»ono± (szkic). Kolejka implementowana na kopcu: ExtractMin - koszt O(log V ); relaksacja - koszt O(log V ) (przywrócenie wªasno±ci kopca); wiersz 7 globalnie wykonywany jest O( V ), a 10, O( E ) razy ( skªadniki O( V log V ) i O( E log V ) w zªo». caªego alg.). O(( V + E ) log V ) (gdy G spójny, O( E log V )). 31 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 4, w π[w] d[w] 1 0 3 4 6 u v d[v] d[u] w(u, v) Q: 1 3 4 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 4, w π[w] d[w] 1 0 3 4 6 u v d[v] d[u] w(u, v) 1 Q: 3 4 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 4, w π[w] d[w] 1 0 3 4 6 u v d[v] d[u] w(u, v) 1 > 0 + 10 Q: 3 4 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 4, w π[w] d[w] 1 0 1 10 3 4 6 u v d[v] d[u] w(u, v) 1 > 0 + 10 Q: 3 4 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 4, w π[w] d[w] 1 0 1 10 3 4 6 u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 Q: 3 4 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 4, w π[w] d[w] 1 0 1 10 3 4 1 7 6 u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 Q: 3 4 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 4, w π[w] d[w] 1 0 1 10 3 4 1 7 6 u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 Q: 3 4 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 4, w π[w] d[w] 1 0 1 10 3 4 1 7 1 10 6 u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 Q: 3 4 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 w π[w] d[w] 1 0 1 10 3 4 1 7 1 10 6 4, u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 4 Q: 3 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 w π[w] d[w] 1 0 1 10 3 4 1 7 1 10 6 4, u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 4 10 > 7 + Q: 3 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 w π[w] d[w] 1 0 1 10 3 4 1 7 4 9 6 4, u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 4 10 > 7 + Q: 3 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 w π[w] d[w] 1 0 1 10 3 4 1 7 4 9 6 4, u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 4 10 > 7 + Q: 3 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 w π[w] d[w] 1 0 1 10 3 4 1 7 4 9 6 4, u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 4 10 > 7 + 3 > 9 + 6 Q: 3 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 w π[w] d[w] 1 0 1 10 3 1 4 1 7 4 9 6 4, u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 4 10 > 7 + 3 > 9 + 6 Q: 3 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 w π[w] d[w] 1 0 1 10 3 1 4 1 7 4 9 6 4, u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 4 10 > 7 + 3 > 9 + 6 6 > 9 + 4, Q: 3 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 w π[w] d[w] 1 0 1 10 3 1 4 1 7 4 9 6 13, 4, u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 4 10 > 7 + 3 > 9 + 6 6 > 9 + 4, Q: 3 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 w π[w] d[w] 1 0 1 10 3 1 4 1 7 4 9 6 13, 4, u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 4 10 > 7 + 3 > 9 + 6 6 > 9 + 4, Q: 3 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 w π[w] d[w] 1 0 1 10 3 1 4 1 7 4 9 6 13, 4, u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 4 10 > 7 + 3 > 9 + 6 6 > 9 + 4, 1 0 < 10 + Q: 3 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 w π[w] d[w] 1 0 1 10 3 1 4 1 7 4 9 6 13, 4, u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 4 10 > 7 + 3 > 9 + 6 6 > 9 + 4, 1 0 < 10 + 9 < 10 + 0 Q: 3 6 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 w π[w] d[w] 1 0 1 10 3 1 4 1 7 4 9 6 13, 4, u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 4 10 > 7 + 3 > 9 + 6 6 > 9 + 4, 1 0 < 10 + 9 < 10 + 0 6 Q: 3 3 / 37
Algorytm - przebieg dla s = 1 Dijkstra(G, w, s) Initialize(G, s); Q := V(G); while Q <> do u := ExtractMin(Q); for ka»dy v Adj[u] do Relax(u, v, w); Relax(u, v, w) if d[v] > d[u] + w(u,v) then d[v] := d[u] + w(u,v); π[v] := u s 7 10 1 3 3 10 0 6 4 4 6 6 w π[w] d[w] 1 0 1 10 3 1 4 1 7 4 9 6 13, 4, Q: u v d[v] d[u] w(u, v) 1 > 0 + 10 1 4 > 0 + 7 1 > 0 + 10 4 10 > 7 + 3 > 9 + 6 6 > 9 + 4, 1 0 < 10 + 9 < 10 + 0 6 3 3 / 37
Algorytm - wyniki s 7 10 1 3 3 10 0 6 4 4 6 6 4, w π[w] d[w] 1 0 1 10 3 1 4 1 7 4 9 6 13, Po zako«czeniu dziaªania algorytmu w wektorze π s zakodowane najkrótsze drogi z s = 1 do poszczególnych wierzchoªków (poprzez system poprzedników), w wektorze d s zakodowane ich dªugo±ci. 33 / 37
Algorytm - wyniki s 7 10 1 3 3 10 0 6 4 4 6 6 4, w π[w] d[w] 1 0 1 10 3 1 4 1 7 4 9 6 13, Po zako«czeniu dziaªania algorytmu w wektorze π s zakodowane najkrótsze drogi z s = 1 do poszczególnych wierzchoªków (poprzez system poprzedników), w wektorze d s zakodowane ich dªugo±ci. I tak np. najkrótsza droga z 1 do 3 to: 1 4 3, o dª. 1. 33 / 37
Uwagi wst pne Algorytm Bellmana-Forda. Dopuszczamy ujemne wagi (w przeciwie«stwie do algorytmu Dijkstry). Algorytm potra wykry ujemne cykle. Nie wykorzystuje kolejki priorytetowej (ªatwiejszy w implementacji). Ma za to wy»sz zªo»ono± od algorytmu Dijkstry. 34 / 37
Specykacja Algorytm Bellmana-Forda. Dane: graf skierowany G = (V, E), funkcja wagi w oraz wierzchoªek ¹ródªowy s V. Wynik: warto± true, gdy G nie zawiera ujemnych cykli osi galnych z s, ponadto: dla ka»dego v V osi galnego z s, warto± d[v] = δ(s, v) oraz poprzednik π[v] na najkrótszej drodze z s do v. Gdy G zawiera ujemny cykl osi galny ze ¹ródªa, warto± false. 3 / 37
Algorytm Bellman-Ford(G, w, s) 1 Initialize(G, s); 3 for i := 1 to V(G) 1 do 4 for ka»da (u,v) E(G) do Relax(u, v, w); 6 for ka»da (u,v) E(G) do 7 if d[v] > d[u]+w(u, v) then 8 return false; 9 return true 10 Zªo»ono± : O( V E ) (p tla w wierszach 3- dominuj ca). 36 / 37
Algorytmy - proste porównanie Zasymulowanie przebiegu algorytmu Bellmana-Forda zostawimy jako wiczenie. W celu porównania obu algorytmów przypomnijmy,»e dla grafu G : 10 1 3 7 10 0 6 4 6 4, algorytm Dijkstry wykonaª 8 relaksacji (tyle ile kraw dzi). Natomiast algorytm Bellmana-Forda wykona (6 1) 8 = 40 relaksacji (patrz wiersze 3- kodu). (Czyli analogiczna tabela przebiegu, jak przedstawili±my przy przebiegu algorytmu Dijkstry, tu b dzie miaªa 40 wierszy). 37 / 37