Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Alberi e arborescenze di costo minimo
Complementi di Ricerca Operativa
Giovanni Righini
Dipartimento di Tecnologie dell’Informazione - Università degli Studi di Milano
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Definizioni - 1
Un grafo G = (V, E) è un albero se e solo se è connesso e aciclico.
Dato un grafo G = (V, E) un sottinsieme F ⊆ E è:
• una foresta se non contiene cicli;
• un connettore se (V, F) è connesso;
• un albero ricoprente se (V, F) è un albero;
• una foresta massimale se non esiste foresta che la contenga.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Definizioni - 2
Un grafo G = (V, E) ha un albero ricoprente se e solo se è connesso.
Dato un grafo connesso G = (V, E), F è un albero ricoprente se e
solo se:
• F è una foresta massimale;
• F è un connettore minimale;
• F è una foresta con |F| = |V| − 1;
• F è un connettore con |F| = |V| − 1.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Definizioni - 3
Dato un grafo G = (V, E) con k componenti connesse, ogni sua
foresta massimale ha |V| − k spigoli.
Essa forma un albero ricoprente in ciascuna delle componenti
connesse di G.
Quindi ogni foresta massimale è anche di massima cardinalità.
Analogamente ogni connettore contiene un connettore di minima
cardinalità.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Il MSTP
Sia G = (V, E) un grafo connesso.
Sia l : E → < una funzione “lunghezza.
Per ogni F ⊆ E definiamo:
l(F) :=
X
l(e)
e∈F
Problema (Minimum Spanning Tree Problem). Trovare un albero
ricoprente di minima lunghezza in G.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Proprietà
Definizione. F è una foresta buona se appartiene ad un albero
ricoprente minimo.
Teorema. Data una foresta buona F e dato uno spigolo e 6∈ F,
F ∪ {e} è una foresta buona se e solo se esiste un taglio C disgiunto
da F tale che e è lo spigolo di lunghezza minima in C.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Dimostrazione - 1
Necessità. Sia T un albero ricoprente minimo che contiene
F ∪ {e}. Sia C il taglio (unico) disgiunto da T ∗ \{e}. Si consideri un
qualunque spigolo f ∈ C. L’insieme T 0 = T ∗ \{e} ∪ {f } è ancora un
albero ricoprente. Dal momento che T ∗ è minimo si ha l(T ∗ ) ≤ l(T 0 )
e quindi l(e) ≤ l(f ). Perciò e è uno spigolo di minima lunghezza in C.
∗
f
C
e
F
e
T*
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Dimostrazione - 2
Sufficienza. Sia T un albero ricoprente minimo contenente F. Sia
P il cammino in T ∗ tra i due estremi dello spigolo e. P contiene
necessariamente almeno uno spigolo f ∈ C, dove C è un taglio
disgiunto da F. Quindi T 0 = T ∗ \{f } ∪ {e} è anch’esso un albero
ricoprente. Dato che l(e) ≤ l(f ) si ha l(T 0 ) ≤ l(T ∗ ). Quindi anche T 0
è un albero ricoprente minimo. Poiché F ∪ {e} è contenuta in T 0 ,
essa è una foresta buona.
P
∗
e
C
f
F
T*
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Algoritmi
Tutti gli algoritmi sfruttano il teorema precedente. L’idea è di partire
con F vuota e di estenderla iterativamente con uno spigolo che
soddisfi il teorema, cioè sia lo spigolo di lunghezza minima in un
taglio C disgiunto da F.
Si ottengono diversi algoritmi a seconda di come si sceglie il taglio C.
I due principali sono:
• Jarnik (1930), Kruskal (1956), Prim (1957), Dijkstra (1959): C è il
taglio che separa la componente connessa cui appartiene un
vertice prefissato.
• Kruskal (1956), Loberman e Weinberger (1957), Prim (1957): C
è il taglio che separa le due componenti connesse cui
appartengono gli estremi di e.
Alberi di costo minimo
Algoritmi di visita di grafi
Algoritmo di Prim (1957)
begin
T :=∅; z:=0;
for v :=1 to n do flag[v ]:=0; flag[r ]:=1;
for v :=1 to n do c[v ]:=l(r , v ); pred[v ]:=r ;
for iterazione:=1 to n − 1 do
cmin:=∞;
for v :=1 to n do
if (flag[v ] = 0) and (c[v ] < cmin) then
v:=v ; cmin:=c[v ];
T :=T ∪ {[pred[v], v]}; z:=z + cmin;
flag[v ] := 1;
for v :=1 to n do
if (flag[v ] = 0) and (l(v, v ) < c[v ]) then
pred[v ] := v; c[v ]:=l(v, v );
end
La complessità è O(n2 ).
Con 2-heaps si ottiene O(m + log n).
Con Fibonacci heaps si ottiene O(m + n log n).
Arborescenze di costo minimo
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Algoritmo di Kruskal (1956) - 1
L’ordinamento degli spigoli richiede O(m log n).
Dopo l’ordinamento la complessità è O(m + n log n) e si ottiene con
semplici liste a puntatori.
Si usa una lista L per ogni componente della foresta corrente.
Per ogni v ∈ V sia r (v ) il capofila della lista Lv cui v appartiene.
Inizialmente r (v ):=v e Lv :={v }.
Ad ogni iterazione è necessario:
• eseguire un test per decidere se il prossimo spigolo e = [u, v ]
chiude un ciclo o no;
• in caso negativo si deve aggiornare la struttura-dati.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Algoritmo di Kruskal (1956) - 2
Il test è semplicemente: r (u) = r (v )?
Il test viene eseguito in tempo costante e al più m volte.
Quindi richiede complessivamente O(m).
Per aggiungere alla foresta corrente lo spigolo e = [u, v ], si sceglie la
lista più piccola tra Lu e Lv (in O(1) con un contatore di elementi
associato ad ogni lista) e si appende la lista più corta a quella più
lunga (anche questo in O(1)).
Si aggiorna quindi r (u 0 ) := r (v ) per ogni u 0 ∈ Lu in O(n).
Nessun nodo può appartenere alla lista più corta più di log n volte,
poiché la dimensione della lista corta come minimo raddoppia ogni
volta.
Quindi la modifica delle liste richiede complessivamente O(n log n).
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Algoritmo di Boruvka (1926)
Richiede che tutte le lunghezze degli spigoli siano diverse tra loro e si
presta alla realizzazione parallela.
F:=∅;
while (|F| < n − 1) do
Per ogni componente K di F
Scegli lo spigolo e minimo in δ(K );
Aggiungilo ad F;
F resta una foresta buona ad ogni iterazione. Infatti, siano
e1 , e2 , . . . , ek gli spigoli aggiunti ad F con l(e1 ) < l(e2 ) < . . . < l(ek ).
Per ogni i = 1, . . . , k, ei è lo spigolo più corto che esce da
F ∪ {e1 , e2 , . . . , ei−1 }, poiché nessuno degli {e1 , e2 , . . . , ei−1 } lascia
la componente Ki . Quindi F resta una foresta buona, come se gli
spigoli venissero aggiunti sequenzialmente.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Algoritmo greedy duale
Toglie spigoli ai connettori invece che aggiungerli alle foreste.
Definizione. Un connettore è buono se contiene un albero ricoprente
minimo.
Teorema. Dato un connettore buono K e uno spigolo e ∈ K , K \{e} è
un connettore buono se e solo se K contiene un ciclo C tale che e è
lo spigolo più lungo in C.
Kruskal (1956): ordinare gli spigoli e partendo dal connettore K = E;
togliere iterativamente lo spigolo più pesante che non sia un ponte
(cioè senza disconnettere il grafo restante).
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Altri algoritmi
Algoritmo di Dijkstra (1960):
Ordinare gli spigoli arbitrariamente.
Quando si trova uno spigolo che forma un ciclo C, scegliere lo
spigolo più lungo in C e cancellarlo.
Algoritmo di Kalaba (1960):
Idem, ma partendo da un albero ricoprente arbitrario.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Breadth-first search
Dati:
• un grafo G = (V, E)
• un vertice s ∈ V,
indichiamo con Vk l’insieme dei vertici raggiungibili da s con un
cammino fatto da almeno k spigoli.
• V0 = {s}
• Vk +1 = {v ∈ V\
Sk
i=0
Vk : ∃u ∈ Vk ∧ ∃[u, v ] ∈ E}.
Definizioni analoghe valgono nel caso di digrafo con archi orientati.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Breadth-first search
Per trovare Vk +1 basta quindi scandire l’insieme degli spigoli (archi)
uscenti dai vertici (nodi) di Vk e inserire in Vk +1 i vertici (nodi) cosı̀
raggiunti, se non sono mai stati raggiunti prima (basta un flag binario
associato al vertice (nodo) per controllarlo).
La complessità dell’algoritmo risultante è O(m), poiché ogni spigolo
viene considerato al massimo due volte (ogni arco al massimo una
volta).
Questo algoritmo determina il cammino minimo da s a qualunque
altro vertice (nodo) del grafo (digrafo) nel caso in cui tutti gli spigoli
(archi) hanno peso unitario.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Algoritmo Breadth-First Search
Algoritmo Breadth-First Search (Berge 1958, Moore 1959):
begin
for v :=1 to n do flag[v ]:=0; flag[s]:=1;
k := 0; Vk := {s};
while Vk 6= ∅ do
Vk +1 := ∅;
for u ∈ Vk do
for [u, v ] ∈ δ(u) do
if (flag[v ]=0) then
Vk +1 := Vk +1 ∪ {v };
flag[v ] := 1;
k := k + 1;
end.
I vertici (nodi) non raggiunti alla terminazione dell’algoritmo non
appartengono alla componente connessa di s.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Depth-First Search (Tarry 1895)
Dati:
• un digrafo D = (N , A)
• un nodo s ∈ N ,
definiamo “scansione” di s (Scan(s) l’operazione (ricorsiva) seguente:
for (s, v ) ∈ δ + (s) do
for (u, v ) ∈ δ − (v ) : u 6= s do
delete (u, v );
Scan(v);
Se tutti i nodi di N sono raggiungibili da s, gli archi non cancellati
dalla Scan(s) formano un’arborescenza radicata in s.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Ordine (pre-)topologico
I nodi di un digrafo si dicono ordinati in ordine topologico se
i < j ∀(vi , vj ) ∈ A.
Quindi un sottoinsieme di nodi N 0 può essere ordinato
topologicamente se e solo se il sottografo indotto A(N 0 ) è aciclico
(cioè non contiene circuiti).
I nodi di un digrafo si dicono ordinati in ordine pre-topologico se vale
la seguente condizione:
vi ≺ v j ⇒ i < j
dove vi ≺ vj ⇔ j è raggiungibile da i ma i non è raggiungibile da j.
Se il digrafo è aciclico, ogni ordine pre-topologico è anche topologico.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Ordine pre-topologico
Teorema. Dato un di-grafo D = (N , A) e un nodo s ∈ N , i nodi
raggiungibili da s possono essere ordinati pre-topologicamente in
O(m0 ), dove m0 è il numero di archi raggiungibili da s.
Dimostrazione. Eseguendo Scan(s) tutti i nodi raggiungibili da s
vengono scanditi. L’ordine in cui termina la scansione di ciascuno è
l’opposto dell’ordine pre-topologico. Infatti, per ogni coppia di nodi u e
v raggiungibili da s, se esiste un cammino da u a v ma non da v a u,
allora Scan(v ) termina prima di Scan(u).
Corollario 1. I vertici di un digrafo D(N , A) possono essere ordinati
pre-topologicamente in tempo lineare.
Dimostrazione. Aggiungere un nodo fittizio s al digrafo e gli archi
(s, v ) ∀v ∈ N ed applicare il teorema precedente.
Corollario 2. I vertici di un digrafo D(N , A) aciclico possono essere
ordinati topologicamente in tempo lineare.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Componenti fortemente connesse
Teorema (Kosaraju e Sharir, 1981. Dato un di-grafo D = (N , A) le
sue componenti fortemente connesse possono essere identificate in
tempo lineare.
Dimostrazione. Ordinare i nodi pre-topologicamente: v1 , v2 , . . . , vn .
Sia N1 l’insieme dei nodi da cui è raggiungibile v1 . Allora N1 è la
componente fortemente connessa a cui appartiene v1 . Infatti ogni vj
in N1 è raggiungibile da v1 per la propietà dell’ordinamento
pre-topologico.
Per il teorema precedente, l’insieme N1 può essere determinato in
tempo O(|A1 |), dove A1 è l’insieme degli archi che hanno la testa in
N1 . Cancellando tutti i nodi in N1 e gli archi in A1 si ottiene un altro
digrafo i cui nodi sono pre-topologicamente ordinati nella stessa
sequenza di prima. Quindi applicando l’operazione ricorsivamente, si
ottengono tutte le componenti fortemente connesse.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Componenti connesse
Per i grafi non orientati vale l’analogo risultato:
Corollario (Shirey, 1969). Le componenti connesse di G = (V, E)
possono essere identificate in tempo lineare.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
r -Arborescenza di costo minimo
Dati:
• un digrafo D = (N , A),
• un vertice r ∈ N ,
• una pesatura degli archi l : A → <.
Problema (Minimum Spanning r -Arborescence Problem). Trovare
la r -arborescenza ricoprente di minimo peso.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Controesempio
Gli algoritmi greedy per l’albero ricoprente minimo non funzionano.
u g
I
@
@
10
1
@
@
10@
@
- gv
15
@
@g
r
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
L’algoritmo - 1
Algoritmo di Chu e Liu (1965), Edmonds (1967), Bock (1971).
Sia A0 = {a ∈ A : l(a) = 0}. Se A0 contiene una r -arborescenza B,
allora B è una r -arborescenza minima. Altrimenti esiste una
componente f.c. K nel digrafo (N , A0 ) tale che r 6∈ K e
l(a) > 0 ∀a ∈ δ − (K ). Sia α = min{l(a) : a ∈ δ − (K )}. Modificare
quindi la pesatura del digrafo: l 0 (a) := l(a) − α ∀a ∈ δ − (K ) e
l 0 (a) = l(a) altrimenti. Cercare quindi una r -arborescenza minima B
rispetto alla nuova pesatura l 0 .
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
L’algoritmo - 2
È sempre possibile scegliere B in modo che contenga un solo arco
entrante in K , dato che K è f.c..
Se avessimo |B ∩ δ − (K )| ≥ 2 esisterebbe un arco a ∈ B ∩ δ − (K ) tale
che B\{a} ∪ A0 contiene ancora una r -arborescenza, B 0 , con
l 0 (B 0 ) ≤ l 0 (B) − l 0 (a) ≤ l 0 (B).
L’arborescenza minima B cosı̀ scelta, è minima anche rispetto alla
pesatura l. Infatti, per ogni altra r -arborescenza B 0 si ha:
l(B 0 ) = l 0 (B 0 ) + α|B 0 ∩ δ − (K )| ≥ l 0 (B 0 ) + α ≥ l 0 (B) + α = l(B).
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Complessità - 1
L’algoritmo ha complessità O(nm), poiché richiede al massimo 2n
iterazioni e ciascuna ha complessità O(m).
Sia k il numero di componenti f.c. nel digrafo (N , A0 ). Sia k0 il
numero di componenti f.c. di (N , A0 ) che non hanno archi entranti di
peso nullo.
Ad ogni iterazione k + k0 diminuisce. Infatti, se K rimane una
componente f.c., ha almeno un arco entrante di peso nullo e quindi k0
diminuisce; se invece K si fonde con un’altra componente f.c., allora
k diminuisce.
Inizialmente k = n e k0 = n. Quindi le iterazioni sono al massimo 2n.
Alberi di costo minimo
Algoritmi di visita di grafi
Arborescenze di costo minimo
Complessità - 2
In tempo O(m) è possibile trovare l’insieme U dei vertici non
raggiungibili da r in (N , A0 ).
Sempre in tempo O(m) è possibile identificare le componenti f.c. del
sottografo indotto da U.
Infine è possibile ordinare i vertici in U in ordine pre-topologico in
modo che il primo vertice appartenga ad una componente f.c. senza
archi entranti di peso nullo.
Quindi ogni iterazione ha complessità O(m).
Tarjan (1977): realizzazione in tempo O(min{n2 , m log n).
Alberi di costo minimo
Algoritmi di visita di grafi
E per quanto riguarda gli alberi...
Arborescenze di costo minimo