Dijkstrův algoritmus (připomenutí) Základní předpoklad w : H R + (nezáporné délky hran) Upravený algoritmus prohledávání do šířky Dijkstra(G,s,w) 1 InitPaths(G,s) 2 S:= ; InitQueue(Q) 3 for každý uzel u U do Enqueue(Q,u) O( U ) 4 while not EmptyQueue(Q) 5 do u:=extractmin(q); S:=S {u} O( U. lg U ) 6 for uzel v Adj[u] 7 do Relax(u,v,w) O( H. lg U ) Možné ještě O( U. lg U + H ) nebo O( U **2) Dijkstrův algoritmus - odst. 6.2 TI 8 / 1
Důkaz správnosti Dijkstrova algoritmu Tvrzení: Při uzavření uzlu u (řádka 5... S:=S {u}) platí d[u] = d(s,u) D: sporem - nechť je d[u] > d(s,u) pro nějaký uzavřený uzel, mějme nejkratší cestu s u, x je poslední uzavřený s uzavřené uzly S x >= y d[y] = d(s,y) d(s,u) < d[u] u spor s vybráním uzlu u, když byl k dispozici uzel y s menší hodnotou TI 8 / 2
Bellmanův-Fordův algoritmus? Co dělat v případě záporně ohodnocených hran? Bellman-Ford(G,s,w) 1 InitPaths(G,s) 2 for i:=1 to U -1 do 3 for každou hranu (u,v) H do Relax(u,v,w) 4 for každou hranu (u,v) H 5 do if d[v] > d[u] + w(u,v) then return false 6 return true Složitost O( U. H )? Proč má nyní Relax konstantní časovou složitost? Bellman-Ford algoritmus - odst. 6.3 TI 8 / 3
? Nelze B-F algoritmus nějak upravit / zrychlit? Co když zavedeme frontu uzlů s úspěšným Relax a bereme jen hrany vycházející z těchto uzlů? ukončení - při vyprázdnění fronty problém - co když se fronta nevyprázdní? v nejhorším případě zase O( U. H ) Nejkratší cesty pro acyklické grafy 1 Topologicky uspořádáme uzly grafu G 2 InitPaths(G,s) 3 for každý uzel u v pořadí podle topologického uspořádání 4 do for každé v Adj[u] 5 do Relax(u,v,w)?? Složitost?? Bellman-Ford algoritmus - odst. 6.3 TI 8 / 4
Nejkratší cesty mezi všemi páry uzlů Označme U = n n x Dijkstra... O(n 2. lg n + n. H ) Fib. halda O( H. n. lg n) binární halda O(n 3 ) sekvenční fronta Ale POZOR - jen pro nezáporné ohodnocení, jinak n x Bellman-Ford... O(n 2. H ) ~ O(n 4 )!?? Jde to lépe? ANO Kap. 7 TI 8 / 5
Nejkratší cesty a násobení matic Graf G reprezentujeme maticí w-délek W (vychází z matice sousednosti V a zahrnuje současně délky hran w): pro i = j w ij = w(u i, u j ), i j, (u i,u j ) H jinak matice w-vzdáleností D = [ d ij ] : d ij = d w (u i,u j ) matice předchůdců P = [ p ij ] p ij = nil... i=j nebo neexistuje cesta u i u j, u k... u k je předchůdce u j na cestě u i u j Cesty a násobení matic - odst. 7.1 TI 8 / 6
Cesty s omezeným počtem hran Předpoklad: nemáme záporné cykly! Nechť P je cesta u i u j, která je tvořena max. m hranami a je nejkratší (podle w-délky) u i m hran P u j w(p) = w(p') + w kj (cesty tvořené m hranami m-1 hran P' w kj vzniknou prodloužením cest o m-1 hranách) u k Cesty a násobení matic - odst. 7.1 TI 8 / 7
d (m) ij... w-délka cesty P d () ij = pro i=j jinak Pro m=1, 2,..., n-1 máme formuli d ij (m) = min (d (m-1) ij, min (d (m-1) ik + w kj )) přes všechna k = min (d (m-1) ik + w kj ) přes všechna k (w jj = ) Operace "přinásobování" maticí W: D'' := D'. W 1 for i:=1 to n do 2 for j:=1 to n do 3 x:= ; 4 for k:=1 to n do x := min (x, d'[i,k] + w[k,j]) 5 d''[i,j] := x Cesty a násobení matic - odst. 7.1 TI 8 / 8
Nyní pronásobení použijeme D (1) = D ().W, D (2) = D (1).W = W 2,..., D (n-1) = W n-1? Složitost? O(n 4 )? Můžeme násobení zrychlit? D (1) = W, D (2) = W 2, D (4) = W 4,..., W 2**k D (2) = W 2, k= horní celá část lg(n-1), tedy složitost?a co paměťová složitost? O(n 3. lg n) Cesty a násobení matic - odst. 7.1 TI 8 / 9
Algoritmus Floyd-Warshall Cesta P : u i u j s vnitřními uzly z {u 1, u 2,..., u k } d ij (k) - délka minimální cesty P u i {u 1, u 2,..., u k-1 } u j d ij () = w ij, u k d ij (k) = min (d ij, d ik + d kj ) d ij (n) = d ij Floyd-Marshall - odst. 7.2 TI 8 / 1
Algoritmus Floyda-Warshala 1 D () := W 2 for k:=1 to n do 3 for i:=1 to n do 4 for j:=1 to n do 5 d (k) : ij = min (d ij, d ik + d kj ) 6 return D (n)!!! Složitost O(n 3 )!!!? A co paměť?? A co, když chceme znát cesty, ne jen vzdálenosti? Floyd-Marshall - odst. 7.2 TI 8 / 11
Výpočet matice předchůdců: p () ij = nil pro i=j nebo w ij = i jinak (tedy (u i,u j ) H) p (k) ij = p ij d ij d ik + d kj p kj d ij > d ik + d kj Reflexivně-tranzitivní uzávěr grafu (relace) W = V + E d ij (k) = d ij (d ik d kj ) Floyd-Marshall - odst. 7.2 TI 8 / 12
Johnsonův aloritmus Pro řídké grafy ( H < O(n 2 )) je O( H.n) lepší než O(n 3 ) Idea: n x Dijkstra, ale co s w(h) <?? Přehodnocení w w' takové, že pro každé u,v je minimální cesta podle w' minimální také podle w w'(u,v) Johnson - odst. 7.3 TI 8 / 13
Úprava G na G': přidáme uzel U' = U {s} a hrany H = H {(s,u): u U}, w(h) = pro nové hrany s v u položíme h(u)=d(s,u)... platí h(v) h(u) + w(u,v), tedy w'(u,v) = w(u,v) + h(u) - h(v)!!! Johnson - odst. 7.3 TI 8 / 14
Johnsonův algoritmus 1 G G' 2 Bellman-Ford(G',w,s) pokud false STOP... O(n. H ) 3 for každý uzel u U do h(u):=d(s,u) 4 for každou hranu (u,v) H do w'(u,v):=w(u,v)+h(u)-h(v) 5 for každý uzel u U n. O(n. lg n + H ) Fib. heap 6 do Dijkstra(G, w', u) 7 for každý uzel v U do d(u,v) := d'(u,v)-h(u)+h(v) O(n. H. lg n) pro binární heap Johnson - odst. 7.3 TI 8 / 15
Příklad: -2-2/ 3/1 2/3 3/1 3/3 s 4/4 6/7 1/ 4/4-1/ -1 h(u) = min (, délka nejkratší cesty s u) w'(u,v) = w(u,v) + h(u) - h(v) Dále Johnson - odst. 7.3 TI 8 / 16
Algebraické souvislosti Floyd-Marshall: d ij (k) = min (d ij, d ik + d kj ) dvojoperace min, + označíme, efekt složení dvou spojení u v v x efekt kombinování alternativních spojení u v?jaké vlastnosti musí tyto operace mít, aby to fungovalo? Algebraické souvislosti - odst. 7.4 TI 8 / 17
Polookruh P = P,,,, 1 : a (b c) = (a b) c P,, a = a = a je komutativní a b = b a monoid a a = a idempotence a (b c) = (a b) c P,, 1 a 1 = 1 a = a je monoid a = a = s nulovým prvkem a (b c) = (a b) (a c) distributivnost (b c) a = (b a) (c a) zleva a zprava Algebraické souvislosti - odst. 7.4 TI 8 / 18
Uzavřený polookruh: a 1 a 2 a 3... je definováno pro lib. a 1, a 2, a 3,... a je asociativní, komutativní, idempotentní a navíc distributivní vůči Kdy máme mnoho spojení? Když máme cykly! Uzávěr c* = 1 c (c c) (c c c)... * = 1, c c* = c* c, c* = 1 (c* c),... Příklady polookruhů R + { }, min, +,, a* = min (, a, a+a, a+a+a,...) = R {, - }, min, +,, a* = nebo - Algebraické souvislosti - odst. 7.4 TI 8 / 19