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