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
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.
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, algorytmBellmana-Forda, realizuj¡cy zbli»one zadanie. Ma on gorsz¡ zªo»ono±¢ ale jest prostszy w implementacji (nie korzysta z kolejki priorytetowej).
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.
Graf z wagami
DenicjaGrafem z wagami nazywamy graf (skierowany) G = (V , E) wraz zfunkcj¡ 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.
Przykªad
Na rysunku grafu warto±ci funkcji wagi zaznaczamy zazwyczaj przy kraw¦dziach: -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - −6 w g wg wg w g wg wg 1 2 3 4 5 6
Powy»szy diagram przedstawia graf G = (V , E), gdzie
V = {1, 2, 3, 4, 5, 6},
E = { (1, 2), (2, 1), (1, 5), (1, 4), (4, 5), (2, 5), (5, 3), (5, 6) },
z funkcj¡ wagi w : E → R okre±lon¡:
w(1, 2) = 10 w(2, 1) = 5 w(1, 5) = 10 w(1, 4) = 7 w(4, 5) = 2 w(2, 5) = 20 w(5, 3) = −6 w(5, 6) = 4, 5.
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) ∈ Mn×n(Z)
o wspóªczynnikach: Ai,j =
0, (i, j) /∈ E, w((i, j)), (i, j) ∈ E (analogicznie w wersji niezorientowanej).
Reprezentacje grafu z wagami
Przykªad wagowej macierzy s¡siedztwa.
-10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - −6 w g wg wg w g wg wg 1 2 3 4 5 6 Ai,j 1 2 3 4 5 6 1 0 10 0 7 10 0 2 5 0 0 0 20 0 3 0 0 0 0 0 0 4 0 0 0 0 2 0 5 0 0 −6 0 0 4, 5 6 0 0 0 0 0 0
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).
Reprezentacje grafu z wagami
Przykªad wagowych list s¡siedztwa.
-10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - −6 w g wg wg w g wg wg 1 2 3 4 5 6 L[i] 1 → {2; 10}→ {5; 10} → {4; 7} 2 → {1; 5} → {5; 20} 3 4 → {5; 2} 5 → {3; −6} → {6; 4, 5} 6
Reprezentacje grafu z wagami
Lista kraw¦dzi (wagowa):
[ [u1,v1,w(u1,v1)], [u2,v2,w(u2,v2)], . . . , [um,vm,w(um,vm)] ], gdzie E = { (ui,vi) : i = 1, . . . , m }.
Reprezentacje grafu z wagami
Przykªad wagowej listy kraw¦dzi.
-10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - −6 w g wg wg w g wg wg 1 2 3 4 5 6 [ [1, 2, 10], [2, 1, 5], [1, 5, 10], [1, 4, 7], [4, 5, 2], [2, 5, 20], [5, 3, −6], [5, 6, 4,5] ]
Waga drogi
Dla dowolnej drogi P = (v0,v1, . . . ,vk)w grae G = (V , E),
vi ∈V , deniujemy jej wag¦jako liczb¦
w(P) :=Xk
i=1
w((vi−1,vi)).
Czyli rozszerzamy denicj¦ funkcji w z kraw¦dzi na wszystkie drogi. Przykªad. 10 - 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - −6 w g wg wg w g wg wg 1 2 3 4 5 6 w((1, 2, 5, 3)) = 10 + 20 − 6 = 24, w((1, 2, 1, 4)) = 10 + 5 + 7 = 22, w((1, 2, 1, 2, 5, 6)) = 10 + 5 + 10 + 20 + 4, 5 = 49, 5.
Najkrótsze drogi w grae z wagami
Ustalmy graf G = (V , E) z wagami w : E → R.
Denicja
Waga najkrótszej drogiz u do v, dla u, v ∈ V , to liczba δ(u, v) :=
(
min{w(P) : u v }, gdy istnieje droga z u do v ,P
∞, w p.p.
u v oznacza, »e P jest drog¡ z u do v .P
Uwaga
Minimum w denicji nie zawsze istnieje! Wrócimy do tego za chwil¦.
Najkrótsze drogi w grae z wagami
Przykªad. -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - −6 w g wg wg w g wg wg 1 2 3 4 5 6 δ(1, 2) = 10, δ(1, 5) = 9, δ(2, 5) = 14, δ(1, 6) = 13, 5.Problem cykli ujemnych
Rozwa»my graf z wagami:
5 A A A K 5 -−15 w g w g wg 1 2 3 Wówczas w(1, 2, 3) = −10, w(1, 2, 3, 1, 2, 3) = −15, w(1, 2, 3, 1, 2, 3, 1, 2, 3) = −20, ...
Czyli warto±¢ δ(1, 3) = min{w(P) : u v } jest nieokre±lona!P 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¡¢).
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. 2 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.
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. 2 Algorytm Bellmana-Forda.
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 .
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 = −∞.
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)
begin
ifd[v] > d[u] + w(u,v)then begin
d[v] := d[u] + w(u,v); π[v] := u
end end;
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 2 (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.).
Inicjalizacja
W obu algorytmach wykorzystamy nast¦puj¡c¡ inicjalizacj¦ wektorów π i d: Initialize(G, s) begin forka»dy v ∈ V(G)do begin d[v] := ∞; π[v] := ∞ end; d[s] := 0 end;
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.
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.
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].
Kolejka priorytetowa - przypomnienie
Przypomnijmy, »e kolejk¦ priorytetow¡ najefektywniej implementuje si¦ przy pomocykopca.
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++
Kolejka priorytetowa - relaksacja
Uwaga techniczna: W procedurze relaksacji uaktualniamy warto±ci wektora d (czyli priorytety):
Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin
d[v] := d[u] + w(u,v); π[v] := u
end end;
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!
Algorytm
Dijkstra(G, w, s) 1 begin 2 Initialize(G, s); 3 S := ∅; 4 Q := V(G); 5 while Q <> ∅do 6 begin 7 u := ExtractMin(Q); 8 S := S ∪ {u};9 forka»dy v ∈ Adj[u]do
10 Relax(u, v, w);
11 end
12 end;
Najwa»niejsze w dowodzie poprawno±ci: dla ka»dego u dodawanego do S mamy d[u] = δ(s, u).
Algorytm - zªo»ono±¢
Dijkstra(G, w, s) 1 begin 2 Initialize(G, s); 3 S := ∅; 4 Q := V(G); 5 while Q <> ∅do 6 begin 7 u := ExtractMin(Q); 8 S := S ∪ {u};9 forka»dy v ∈ Adj[u]do
10 Relax(u, v, w);
11 end
12 end;
Zªo»ono±¢ (szkic). Kolejka implementowana na tablicy:
ExtractMin na tablicy: O(|V |);
wiersz 7 wykonany |V | razy (⇒ skªadnik O(|V |2)w zªo». caªego
algorytmu);
dodatkowo wiersz 10 globalnie wykonywany jest O(|E|) razy.
Algorytm - zªo»ono±¢
Dijkstra(G, w, s) 1 begin 2 Initialize(G, s); 3 S := ∅; 4 Q := V(G); 5 while Q <> ∅do 6 begin 7 u := ExtractMin(Q); 8 S := S ∪ {u};9 forka»dy v ∈ Adj[u]do
10 Relax(u, v, w);
11 end
12 end;
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.).
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q:=V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do
Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 g 1 g 4 5g g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 ∞ ∞ 3 ∞ ∞ 4 ∞ ∞ 5 ∞ ∞ 6 ∞ ∞ Q: 1 2 3 4 5 6 u v d[v] d[u] w(u, v) 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 5 3 ∞ > 9 + 6 5 6 ∞ > 9 + 4, 5 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u:=ExtractMin(Q);
forka»dy v ∈ Adj[u]do
Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 g 4 5g g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 ∞ ∞ 3 ∞ ∞ 4 ∞ ∞ 5 ∞ ∞ 6 ∞ ∞ Q: 2 3 4 5 6 u v d[v] d[u] w(u, v) 1 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 5 3 ∞ > 9 + 6 5 6 ∞ > 9 + 4, 5 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 g 4 5g g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 ∞ ∞ 3 ∞ ∞ 4 ∞ ∞ 5 ∞ ∞ 6 ∞ ∞ Q: 2 3 4 5 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 4 5 10 > 7 + 2 5 3 ∞ > 9 + 6 5 6 ∞ > 9 + 4, 5 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 g 4 5g g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 ∞ ∞ 4 ∞ ∞ 5 ∞ ∞ 6 ∞ ∞ Q: 2 3 4 5 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 4 5 10 > 7 + 2 5 3 ∞ > 9 + 6 5 6 ∞ > 9 + 4, 5 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 g 4 5g g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 ∞ ∞ 4 ∞ ∞ 5 ∞ ∞ 6 ∞ ∞ Q: 2 3 4 5 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 5 3 ∞ > 9 + 6 5 6 ∞ > 9 + 4, 5 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 g 4 5g g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 ∞ ∞ 4 1 7 5 ∞ ∞ 6 ∞ ∞ Q: 2 3 4 5 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 5 3 ∞ > 9 + 6 5 6 ∞ > 9 + 4, 5 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 g 4 5g g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 ∞ ∞ 4 1 7 5 ∞ ∞ 6 ∞ ∞ Q: 2 3 4 5 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 5 6 ∞ > 9 + 4, 5 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 g 4 5g g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 ∞ ∞ 4 1 7 5 1 10 6 ∞ ∞ Q: 2 3 4 5 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 5 6 ∞ > 9 + 4, 5 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u:=ExtractMin(Q);
forka»dy v ∈ Adj[u]do
Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5g g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 ∞ ∞ 4 1 7 5 1 10 6 ∞ ∞ Q: 2 3 5 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 4 5 6 ∞ > 9 + 4, 5 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5g g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 ∞ ∞ 4 1 7 5 1 10 6 ∞ ∞ Q: 2 3 5 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5g g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 ∞ ∞ 4 1 7 5 4 9 6 ∞ ∞ Q: 2 3 5 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u:=ExtractMin(Q);
forka»dy v ∈ Adj[u]do
Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5wg g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 ∞ ∞ 4 1 7 5 4 9 6 ∞ ∞ Q: 2 3 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 5 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5wg g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 ∞ ∞ 4 1 7 5 4 9 6 ∞ ∞ Q: 2 3 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 5 3 ∞ > 9 + 6 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5wg g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 5 15 4 1 7 5 4 9 6 ∞ ∞ Q: 2 3 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 5 3 ∞ > 9 + 6 2 5 9 < 10 + 20 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5- - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5wg g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 5 15 4 1 7 5 4 9 6 ∞ ∞ Q: 2 3 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 5 3 ∞ > 9 + 6 5 6 ∞ > 9 + 4, 5 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5- - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5wg g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 5 15 4 1 7 5 4 9 6 5 13, 5 Q: 2 3 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 5 3 ∞ > 9 + 6 5 6 ∞ > 9 + 4, 5 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u:=ExtractMin(Q);
forka»dy v ∈ Adj[u]do
Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5wg w g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 5 15 4 1 7 5 4 9 6 5 13, 5 Q: 3 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 5 3 ∞ > 9 + 6 5 6 ∞ > 9 + 4, 5 2 6 − 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5wg w g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 5 15 4 1 7 5 4 9 6 5 13, 5 Q: 3 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 5 3 ∞ > 9 + 6 5 6 ∞ > 9 + 4, 5 2 1 0 < 10 + 5 3 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u := ExtractMin(Q);
forka»dy v ∈ Adj[u]do Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5wg w g 2 g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 5 15 4 1 7 5 4 9 6 5 13, 5 Q: 3 6 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 5 3 ∞ > 9 + 6 5 6 ∞ > 9 + 4, 5 2 1 0 < 10 + 5 2 5 9 < 10 + 20
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u:=ExtractMin(Q);
forka»dy v ∈ Adj[u]do
Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5wg w g 2 w g 6 g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 5 15 4 1 7 5 4 9 6 5 13, 5 Q: 3 u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 5 3 ∞ > 9 + 6 5 6 ∞ > 9 + 4, 5 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 −
Algorytm - przebieg dla s = 1
Dijkstra(G, w, s) begin Initialize(G, s); Q := V(G); while Q <> ∅do begin u:=ExtractMin(Q);forka»dy v ∈ Adj[u]do
Relax(u, v, w);
end end; Relax(u, v, w)
begin
ifd[v] > d[u] + w(u,v)then begin d[v] := d[u] + w(u,v); π[v] := u end end; -10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5wg w g 2 w g 6 w g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 5 15 4 1 7 5 4 9 6 5 13, 5 Q: u v d[v] d[u] w(u, v) 1 2 ∞ > 0 + 10 1 4 ∞ > 0 + 7 1 5 ∞ > 0 + 10 4 5 10 > 7 + 2 5 3 ∞ > 9 + 6 5 6 ∞ > 9 + 4, 5 2 1 0 < 10 + 5 2 5 9 < 10 + 20 6 −
Wst¦p Grafy z wagami Przygotowanie Dijkstra Bellman-Ford
Algorytm - wyniki
-10 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5wg w g 2 w g 6 w g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 5 15 4 1 7 5 4 9 6 5 13, 5Po 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.
Algorytm - wyniki
-10 5 ? ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g 1 wg wg w g wg wg s 2 3 4 5 6 w g 1 w g 4 5wg w g 2 w g 6 w g 3 w π[w] d[w] 1 ∞ 0 2 1 10 3 5 15 4 1 7 5 4 9 6 5 13, 5Po 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.
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).
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.
Algorytm
Bellman-Ford(G, w, s)1 begin
2 Initialize(G, s);
3 for i := 1to |V(G)|−1do
4 for ka»da (u,v)∈ E(G)do
5 Relax(u, v, w); 6 for ka»da (u,v)∈ E(G)do
7 if d[v] > d[u]+w(u, v)then
8 returnfalse; 9 returntrue 10 end;
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 5 ? 7 ? 20 @ @ @ R 10 -2 4,5 - 6 w g wg wg w g wg wg 1 2 3 4 5 6
algorytm Dijkstry wykonaª 8 relaksacji (tyle ile kraw¦dzi). Natomiast algorytm Bellmana-Forda wykona (6 − 1) · 8 = 40 relaksacji (patrz wiersze 3-5 kodu).
(Czyli analogiczna tabela przebiegu, jak¡ przedstawili±my przy przebiegu algorytmu Dijkstry, tu b¦dzie miaªa 40 wierszy).