Cammini minimi in un grafo orientato pesato Algoritmi di Dijkstra e Bellman-Ford per il problema del cammino minimo da sorgente singola Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Un problema di “percorso” Dati una mappa stradale (con distanze ad es. in chilometri) ed un punto di partenza s trovare i percorsi più brevi da s a ciascuna delle altre località Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Problemi di ottimizzazione Problema: Problema:data datauna unamisura misura(costo (costoooobiettivo) obiettivo)individuare individuareuna una soluzione soluzioneammissibile ammissibilelalacui cuimisura misurasia siaminima minimaoomassima massima Senza offesa, questi due vorrei vederli il meno possibile Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Grafi pesati p: A→ℜ 2.6 I pesi possono essere anche negativi Anche se non nel mio caso 4.5 − 7.1 − 2.1 3.5 9 1.8 1.5 5.1 6.9 2.6 G = (N, A, p) Funzione “peso” Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Peso di un cammino e distanze Il peso di un cammino è la somma dei pesi dei suoi archi: p (v0 , v1 , K , vk ) = p (v0 , v1 ) + p (v1 , v2 ) + L + p (vk −1 , vk ) La distanza di un vertice dall’altro è il minimo dei pesi tra tutti i cammini che congiungono il primo al secondo (se esistono): min{ p (c) : c cammino da u a v} se ne esistono δ (u , v) = ∞ altrimenti Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Cicli a somma negativa b 2 u 1 –1 c 3 a 5 v Ma quanto vale δ(u,v) ? –7 d p (a, b, c, d ) = 2 − 1 − 7 + 5 = −1 Perché δ(u,v) sia sempre definito assumeremo che non ci siano cicli a somma negativa. Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Sottocammini di quello ottimo c2 v1 c1 vi vj c4 vk c3 se p (c3 ) < p (c2 ) allora p (c1c3c4 ) = p (c1 ) + p (c3 ) + p (c4 ) < p (c1 ) + p (c2 ) + p (c4 ) = p (c1c2 c4 ) Se un cammino è ottimo, tali sono tutti i suoi sottocammini. Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Coperture, ovvero soluzioni Un albero T è una copertura di G se è un albero sorgente ed un sottografo di G che comprende tutti i suoi vertici. 3 a b 5 2 c a 1 2 a 3 2 c Ci sono due coperture-soluzioni 5 1 d G c b T1 d b 1 d T2 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Coperture, ovvero soluzioni Se s è la radice di T , v in T e c il cammino da s a v allora: La distanza s, v in T d[v] = p(c) = δT(s,v) 3 a b 5 2 c a 1 2 a 3 2 c b c 5 1 d G T1 d1[c] = 2, d1[b] = 3, d1[d ] = 4 d 2 [c] = 2, d 2 [b] = 7, d 2 [d ] = 8 d b 1 d T2 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Soluzioni ottime T è ottimo per G da s se è una soluzione e per ogni v: La distanza s, v in G d[v] = δG(s,v) 3 a b 5 2 c a 1 2 a 3 2 c T1 è ottimo per G da a 5 1 d G c b T1 d b 1 d T2 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Archi di una soluzione ottima Supponiamo che T sia ottimo per G da s: se (u , v) ∈ T allora d [v] = d [u ] + p (u , v) s c c′ u v ∈T ∉T u′ se (u ′, v) ∉ T allora d [v] ≤ d [u ′] + p (u ′, v) Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Il teorema di Bellman Teorema. Teorema.Se Seper perogni ogniarco arco(u,v), (u,v),d[v] d[v]≤≤d[u] d[u]++p(u, p(u,v), v), con con==quando quando(u,v) (u,v)∈∈T, T, allora alloraTTèèottimo ottimo Per assurdo sia ottimo T′ ma non T: allora esiste w t.c. d′[w] < d[w] Nel cammino che in T′ conduce a w, consideriamo il primo arco (u, v) per cui d′[u] = d[u] ma d′[v] < d[v]: d ′[v] = d ′[u ] + p(u, v) perché T ′ è ottimo = d [u ] + p(u, v) d ′[u ] = d [u ] ≥ d [v ] per ipotesi Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Schema di risoluzione CamminiMinimi (G = (N, A, p), s) foreach v ∈ N do d[v] ← ∞ d[s] ← 0, T ← ∅, S ← {s} while S ≠ ∅ do sia u ∈ S, S ← S – {u} foreach (u, v) ∈ A do rilassamento if d[v] > d[u] + p(u, v) then // c’è un cammino migliore da s a v Se nessun arco della forma (w, v) era in T, allora “rimpiazza” = aggiungi d[v] ← d[u] + p(u, v) rimpiazza in T l’arco incidente in v con (u, v) S ← S ∪ {u} return T Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Cammini minimi e BFS Somiglianze Differenze Da un nodo consideriamo tutti i suoi adiacenti, inoltre: Se v è raggiungibile da più di un cammino allora sarà in S più di una volta 1. S è la Frontiera 2. Esterni = {v: d[v] = ∞} 3. Interni = {v: d[v] < ∞} – S Non si tiene conto del fatto che un vertice possa essere stato visitato Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Algoritmo di Dijkstra Supponiamo che i pesi siano positivi: • S è una coda di priorità dove Priorità(v, S) = d[v] • Se d[v] < ∞ e v ∉ S, allora d[v] = δ (s, v): s c u v ∈T d [u ] = p (c) = δ ( s, u ) ipotesi induttiva p (u , v) = min{ p (u , w) : (u , w) ∈ A} Qui usiamo l’ipotesi che i pesi siano positivi δ ( s, v) non dipende dai nodi ancora da scoprire Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Algoritmo di Dijkstra Dijkstra-Johnson (G = (N, A, p), s) // Pre: p ha valori positivi foreach v ∈ N do d[v] ← ∞; d[s] ← 0; Q ← EmptyPriorityQueue () foreach v ∈ N do Enqueue(v, d[v], Q) // la priorità di ogni v in Q è d[v] while not IsEmptyQueue(Q) do u ← ExtractMin(Q); foreach (u, v) ∈ A do if d[v] > d[u] + p(u,v) then d[v] ← d[u] + p(u,v) Esssenziale se Q è uno heap: la posizione di v cambia rimpiazza in T l’arco incidente in v con (u, v) RedefinePrior(v, d[v], Q) return T Nessun reinserimento Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Esecuzione dell’algoritmo di Dijkstra 4 0 d ∞ b ∞ a 1 10 1 3 ∞ 5 h ∞ 3 1 ∞ e 9 2 ∞ c f 1 i ∞ 7 ∞ g 1 2 j ∞ Iterazione No 0 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Esecuzione dell’algoritmo di Dijkstra ∞ b 4 a 4 0 d 1 10 1 3 ∞ 5 h 1 3 1 ∞ e 9 2 ∞ c f 1 i ∞ 7 ∞ g 1 2 j ∞ Iterazione No 1 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Esecuzione dell’algoritmo di Dijkstra ∞ b 4 a 4 0 d 1 3 e 10 1 ∞ 5 h 1 3 1 6 9 2 ∞ c f 1 i 10 7 ∞ g 1 2 j ∞ Iterazione No 2 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Esecuzione dell’algoritmo di Dijkstra ∞ b 4 a 4 0 d 1 3 e 10 1 ∞ 5 h 1 3 1 5 9 2 ∞ c f 1 i 10 7 ∞ g 1 2 j ∞ Iterazione No 3 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Esecuzione dell’algoritmo di Dijkstra ∞ b 4 a 4 0 d 1 3 e 10 1 8 5 h 1 3 1 5 9 2 ∞ c f 1 i 10 7 ∞ g 1 2 j ∞ Iterazione No 4 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Esecuzione dell’algoritmo di Dijkstra 9 4 a 4 0 d 1 3 8 5 h 1 9 c 3 1 5 e 10 1 2 b 11 f 1 i 9 7 g 15 1 2 j ∞ Iterazione No 5 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Esecuzione dell’algoritmo di Dijkstra 9 4 a 4 0 d 1 3 8 5 h 1 9 c 3 1 5 e 10 1 2 b 11 f 1 i 9 7 g 15 1 2 j 11 Iterazione No 6 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Esecuzione dell’algoritmo di Dijkstra 9 4 a 4 0 d 1 3 8 5 h 1 9 c 3 1 5 e 10 1 2 b 11 f 1 i 9 7 g 15 1 2 j 11 Iterazione No 7 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Esecuzione dell’algoritmo di Dijkstra 9 4 a 4 0 d 1 3 8 5 h 1 9 c 3 1 5 e 10 1 2 b 11 f 1 i 9 7 g 15 1 2 j 11 Iterazione No 8 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Esecuzione dell’algoritmo di Dijkstra 9 4 a 4 0 d 1 3 8 5 h 1 9 c 3 1 5 e 10 1 2 b 11 f 1 i 9 7 g 12 1 2 j 11 Iterazione No 9 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Esecuzione dell’algoritmo di Dijkstra 9 4 a 4 0 d 1 3 8 5 h 1 9 c 3 1 5 e 10 1 2 b 11 f 1 i 9 7 g 12 1 2 j 11 Iterazione No 10 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 E se ci sono pesi negativi? ∞ a 2 0 1 −3 b d ∞ 3 1 c ∞ Iterazione No 0 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 E se ci sono pesi negativi? 2 a 2 0 1 −3 b d ∞ 3 1 c 1 Iterazione No 1 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 E se ci sono pesi negativi? 2 a 2 0 1 −3 b d 4 3 1 c 1 Iterazione No 2 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 E se ci sono pesi negativi? 2 a 2 0 1 −3 b d 3 3 1 c 1 Iterazione No 3 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 E se ci sono pesi negativi? 2 a 2 0 1 −3 b d 3 3 1 c Iterazione No 1 δ (b, d ) = p(b, a, c, d ) = 2 − 3 + 3 = 2 4 Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Un problema con pesi negativi “Un proprietario di TIR è libero di spostare containers da una città all’altra. Un viaggio dalla città i alla città j porta un profitto di pij euro se c’è un container da trasportare, ma provoca una perdita di pij euro se il TIR viaggia scarico. Assumendo profitti pij > 0 e perdite pij < 0, il percorso più vantaggioso tra due città corrisponde ad un cammino minimo, in cui le lunghezze (i pesi) degli archi sono – pij”. Bertossi, esempio 10.1 Per aggirare l’ostacolo proviamo a “rilassare” tutti gli archi a ripetizione Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Algoritmo di Bellman-Ford BF (G = (N, A, p), s) foreach v ∈ N do d[v] ← ∞ Questo algoritmo termina? Se si, entro quante iterazioni? d[s] ← 0, T ← ∅, relax ← true while relax do relax ← false foreach (u, v) ∈ A do if d[v] > d[u] + p(u,v) then relax ← true d[v] ← d[u] + p(u,v) rimpiazza in T l’arco incidente in v con (u, v) return T Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Algoritmo di Bellman-Ford Teorema. Teorema. Se SeGGnon nonha hacicli cicliaasomma sommanegativa negativaed edesiste esisteuna una copertura coperturacon conradice radicein ins,s,allora alloraBF BFtermina terminaentro entronn––11 iterazioni, iterazioni,dove dovenn==|N|. |N|. Sia c = v0, …, vk un cammino ottimo in G, con s = v0: per induzione su k dimostriamo che: i. d[vi] ≥ δ(s, vi), per i = 0, …, k è un invariante di ciclo ii. d[vk] = δ(s, vk) dopo al più k iterazioni E in un cammino ottimo ci sono ≤ n – 1 archi Base: k = 0, allora δ(s, v0) = δ(s, s) = 0 = d[v0] per inizializzazione Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Algoritmo di Bellman-Ford Teorema. Teorema. Se SeGGnon nonha hacicli cicliaasomma sommanegativa negativaed edesiste esisteuna una copertura coperturacon conradice radicein ins,s,allora alloraBF BFtermina terminaentro entronn––11 iterazioni, iterazioni,dove dovenn==|N|. |N|. Passo: k > 0 e c = v0, …, vk – 1, vk : δ ( s, vk ) = p(c) = p(v0 , K, vk −1 ) + p(vk −1 , vk ) = δ (v0 , vk −1 ) + p (vk −1 , vk ) sott. ottimo = d [vk −1 ] + p (vk −1 , vk ) ip. ind. Per ip. ind. d[vk ] ≥ δ(s, vk), e se è > allora per rilassamento d[vk ] = d[vk – 1] + p(vk – 1,vk) = δ(s, vk) dopo la k-esima iterazione. Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Algoritmo di Bellman-Ford Bellman-Ford (G = (N, A, p), s) foreach v ∈ N do d[v] ← ∞ d[s] ← 0, T ← ∅ for i ← 1 to |N|– 1 do foreach (u, v) ∈ A do if d[v] > d[u] + p(u,v) then d[v] ← d[u] + p(u,v) rimpiazza in T l’arco incidente in v con (u, v) return T Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Analisi della complessità Dijkstra-Johnson: ExtractMin si esegue n = |N| volte, mentre RedefinePrior si esegue al più m = |A| volte. • Se Q è un vettore, ExtractMin è O(n), ma RedefinePrior è O(1), dunque O(n2 + m) = O(n2) • Se Q è uno heap, sia ExtractMin che RedefinePrior sono O(log n) mentre l’inizializzazione è O(n), dunque, se una copertura esiste, O(n + n log n + m log n) = O(m log n) Lo heap conviene se m non è Ω(n2) (grafo sparso) Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Analisi della complessità Bellman-Ford: in ognuna delle n – 1 iterazioni si esplorano al più m archi: O(nm) Poiché m è O(n2), abbiamo O(n3). Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19 Il corso di “Algoritmi” è finito: non sei contento? Sicuro se sopravvivo anche questa volta … Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez. 19