Cammini minimi in un grafo orientato pesato

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