Sei sulla pagina 1di 6

Minimum

spunning tree
{ST cup, 13 pur, }
Tra i problemi di minimizzazione che riguardano grafi
pesati, ce n un altro molto importante
Esempio: Un insieme di calcolatori da collegare in rete mediante
rami che collegano un calcolatore a un altro; ciascun ramo ha un
costo (corrispondente, ad esempio, alla lunghezza del cavo)
Cerchiamo di collegarli tutti (cio di progettare un grafo
connesso avente quei vertici) rendendo minimo il costo totale
(definito come la somma dei pesi dei rami coinvolti)
Problema analogo per altre reti di distribuzione in cui i rami siano
tecnicamente non orientati (anche se magari funzionalmente
orientati) e condivisibili da traffico avente sorgenti e/o destinazioni
diverse (rete elettrica, rete del gas, rete idrica, rete stradale)
uno dei problemi pi studiati della teoria dei grafi!
Perch ha forti implicazioni economiche
Un diverso problema di minimo
Cerchiamo di collegarli tutti (cio di progettare un grafo connesso
avente quei vertici) rendendo minimo il costo totale (definito come la
somma dei pesi dei rami coinvolti)
Per definire il problema, bisogna creare un grafo contenente tutti i vertici
da collegare e tutti i rami tecnicamente realizzabili, etichettati con i
rispettivi costi (spesso economici)
Il grafo deve essere connesso, altrimenti il problema non risolubile
Tra questi, bisogna selezionare un insieme di rami che
renda minimo il costo totale, pur conservando la
connettivit del grafo
Non si tratta di trovare un insieme di percorsi minimi da un
vertice sorgente verso tutti gli altri vertici o tra tutte le
coppie di vertici, ma di cercare uno spanning subgraph
connesso in cui la somma dei pesi dei rami sia minima
Un diverso problema di minimo
Non si tratta di trovare un insieme di percorsi minimi da un
vertice sorgente o tra tutte le coppie di vertici, ma di cercare
uno spanning subgraph connesso in cui la somma dei
pesi dei rami sia minima
Esempio
Un diverso problema di minimo
B
D
C
F
E
7
4
2
8
5
7
3
9
8
B
D
C
A
F
E
7
4
2
5
3
A
Cercare uno spanning subgraph connesso di costo minimo
Ipotesi: grafo semplice, connesso, non orientato, con pesi positivi
Propriet: Uno spanning subgraph connesso di costo minimo
uno spanning tree
Per assurdo: Se lo spanning subgraph non un albero, vuol dire che ha
almeno un ciclo. Sia e = (u, v) un ramo di tale ciclo.
Se eliminiamo e dallo spanning subgraph, il sottografo rimane connesso:
infatti, qualsiasi percorso che conteneva e pu sostituire tale ramo con un
sottopercorso che collega u e v attraverso la parte restante del ciclo (che non
pi un ciclo).
Il nuovo spanning subgraph ha costo totale minore del precedente, perch
manca il costo di e. Con la stessa procedura, tagliamo tutti i cicli presenti
nel sottografo, rimanendo con un albero che ancora spanning e ha costo
inferiore al sottografo di partenza, che, quindi, non aveva costo minimo.
Assurdo
Minimum Spanning Subgraph
Problema: dato un grafo semplice, connesso, non
orientato, con pesi positivi, cercare uno spanning
tree di costo minimo
Esistono molti algoritmi che risolvono il problema,
con le stesse prestazioni asintotiche, O[(n + m) log n]
Cio O(m log n)
e anche O(m log m), perch il grafo connesso
Alcuni sono ottimizzati per situazioni specifiche
(es. grafi densi, grafi sparsi, ecc.)
Vediamo lalgoritmo di Prims-Jarnik, che funziona in
modo analogo allalgoritmo di Dijkstra
Minimum Spanning Tree (MST)
Algoritmo di Prims-Jarnik per il calcolo di MST
Scegli (a caso) un vertice, s, da cui partire e inseriscilo nella
nuvola, inizialmente vuota
Finch la nuvola non contiene tutti i vertici del grafo
Metti nella nuvola il vertice v, esterno alla nuvola, che
connesso da un ramo e di costo minimo a un qualsiasi
vertice interno alla nuvola
Attenzione: Dijkstra diverso, inserisce nella nuvola il vertice
connesso da un percorso minimo alla sorgente (usando
letichetta per ottenere questa informazione)
Etichetta il ramo e come appartenente al MST
Fine! Si dimostra che funziona, cio che linsieme dei soli
rami etichettati individua uno spanning tree di costo minimo
MST Prims-Jarnik
In realt, implementato in questo modo semplice,
lalgoritmo ha prestazioni scadenti
Richiede n iterazioni (una per ogni vertice)
Ad ogni iterazione, deve analizzare tutti i vertici esterni alla nuvola
e, per ognuno di essi, tutti i rami incidenti (invocando
incidentEdges): il numero totale di rami analizzati ad ogni
iterazione O(m) (anche se diminuisce dopo ogni iterazione)
Lanalisi di un ramo richiede linvocazione di opposite per
verificare se il ramo collega il nodo a un nodo interno alla nuvola
(immaginando di etichettare opportunamente i nodi entrati nella
nuvola, in modo da non dover verificare la loro presenza allinterno)
Lalgoritmo , quindi, O(nm)
Anche O(m
2
), perch in un grafo connesso n O(m)
Per un grafo denso O(n
3
), per un grafo sparso O(n
2
)
MST Prims-Jarnik
Finch la nuvola non contiene tutti i vertici del grafo
Metti nella nuvola il vertice v, esterno alla nuvola, che connesso da
un ramo di costo minimo a un vertice interno alla nuvola
Lalgoritmo di Prims-Jarnik usa etichette simili allalgoritmo
di Dijkstra: ogni vertice ha unetichetta che indica il peso del
ramo (conosciuto!) di costo minimo che lo connette a un
vertice qualsiasi appartenente alla nuvola
In Dijkstra letichetta era la lunghezza del percorso (conosciuto!) di
costo minimo dal vertice alla sorgente
Inizializzazione: per la sorgente s etichetta zero, per tutti
gli altri vertici etichetta infinita
Rilassamento: quando si inserisce v nella nuvola
Per ogni vertice u adiacente a v, se il peso w del ramo
e = (u, v) minore di d(u), allora d(u) = w
MST Prims-Jarnik
Lanalisi delle prestazioni dellalgoritmo di Prims-Jarnik
identica a quella vista per lalgoritmo di Dijkstra
Usando una coda prioritaria modificabile realizzata con
heap come contenitore esterno alla nuvola e un grafo
realizzato con liste di adiacenza, si ottengono prestazioni
O[(n + m) log n], decisamente migliori di O(nm)
Dato che il grafo , per ipotesi, connesso, allora n O(m) e
le prestazioni sono
O[(n + m) log n] O(m log n) O(m log m)
Lalgoritmo di Kruskal funziona diversamente ma ha le
stesse prestazioni
MST Prims-Jarnik
Gli algoritmi di Dijkstra e di Prims-Jarnik sono molto simili:
sono esemplari del medesimo paradigma di programmazione,
usato per risolvere molti problemi diversi
il paradigma greedy (goloso) per la progettazione di
algoritmi
Caratteristica comune a molti algoritmi di ottimizzazione
Si costruisce in fasi successive la soluzione ottima per un
problema: ogni fase prevede di compiere una scelta
Un algoritmo greedy goloso: ogni volta sceglie la cosa
pi appetibile
Ogni volta che richiesto di scegliere un elemento utile per la
costruzione progressiva della soluzione, un algoritmo greedy sceglie
lelemento che ottimizza, in quel momento, qualche propriet:
sceglie, quindi, il valore localmente ottimo
Dijkstra e Prims-Jarnik
Il fatto che una sequenza di scelte localmente ottime
porti alla costruzione di una soluzione globalmente
ottima , nella prassi comune, un colpo di fortuna
Esempio che NON funziona: nella ricerca di un percorso minimo
tra due vertici di un grafo pesato, partiamo da uno dei due vertici
e costruiamo il percorso scegliendo ogni volta il ramo di costo
minimo tra quelli incidenti e non ancora scelti
Per andare da A a D trova un percorso (addirittura non semplice) di
lunghezza 29; viceversa, per andare da D a A trova un percorso di
lunghezza 14; il percorso minimo , in entrambi i casi, A-B-D = 9
Algoritmi greedy
B
D
C
F
E
7
4
2
10
5
7
3
9
8
A
B
D
C
F
E
7
4
2
10
5
7
3
9
8
A
Il fatto che una sequenza di scelte localmente ottime
porti alla costruzione di una soluzione globalmente
ottima , nella prassi comune, un colpo di fortuna
In generale, gli algoritmi greedy
Sono abbastanza difficili da progettare
In pratica, si tratta di individuare una propriet greedy,
cio una funzione il cui valore localmente ottimo possa
guidare la scelta, e una modalit efficiente per il suo
aggiornamento
particolarmente difficile dimostrare che sono corretti
Sono molto efficienti
Nel corso di Dati e Algoritmi 2 si vedranno linee guida
per la progettazione di algoritmi greedy
Algoritmi greedy
Un grafo connesso privo di cicli un albero (libero)
Un "albero con radice", T, costituito da un insieme di nodi tra i quali
esiste una relazione di tipo genitore/figlio rappresentata mediante rami
Se T non vuoto, uno e uno solo dei suoi nodi non ha genitore e
viene chiamato radice di T
Ogni nodo diverso dalla radice ha un unico (nodo) genitore, p
I nodi aventi p come genitore sono figli di p
L'insieme di nodi e rami che costituisce T, considerato come grafo,
deve essere connesso
Osserviamo che un albero con radice, considerato come grafo,
oltre ad essere, per definizione, connesso, anche privo di cicli
(altrimenti, come si pu facilmente dimostrare, esisterebbe un
nodo con due genitori), quindi
un albero con radice, considerato come grafo, un
albero libero ("un albero un albero")
Alberi liberi e alberi con radice
Un albero con radice, considerato come
grafo, un albero libero
Viceversa, dato un albero libero, si pu costruire
un albero con radice in questo modo
Scelgo un nodo qualsiasi, r, dell'albero libero G e lo "nomino" radice
Faccio un attraversamento BFS(G, r), che avr soltanto rami DISCOVERY
(perch G un albero)
Ricordo che ogni ramo DISCOVERY connette due nodi di livelli adiacenti:
ognuno di tali rami rappresenta una relazione genitore/figlio nell'albero con
radice, dove il genitore il nodo avente livello inferiore tra i due (l'altro
nodo, ovviamente, il figlio)
Questa struttura rispetta la definizione di "albero con radice" (ricordando
che un albero libero un grafo connesso)
Si sottolinea la scelta arbitraria di un nodo dell'albero libero come radice
del albero con radice
Alberi liberi e alberi con radice
Srufi orientuti
{ST cup, 13 pur, 4}
Un grafo orientato se tutti i suoi rami sono orientati
Un ramo orientato una coppia orientata di vertici, (u, v) (v, u)
In un grafo orientato (o digrafo, directed graph) si distinguono
percorsi e percorsi orientati
Un percorso orientato se tutti i suoi rami vengono attraversati
nella direzione in cui sono orientati
Attenzione: la definizione di grafo connesso prescinde
dallorientamento
Questo grafo connesso ma non esiste
un percorso orientato tra alcune coppie
di suoi vertici (ad esempio, da E a B)
Si dice che B non raggiungibile da E
Il vertice v raggiungibile dal vertice u se esiste un
percorso orientato da u a v
Grafo orientato
A
C
E
B
D
F
Il problema della raggiungibilit caratteristico dei grafi
orientati: qual linsieme di vertici raggiungibili partendo
da un determinato vertice?
Analogamente al concetto di componente connesso di
un grafo, in un grafo orientato si definisce linsieme dei
vertici raggiungibili da un determinato vertice
La determinazione dellinsieme di raggiungibilit per un vertice
si effettua con un attraversamento (DFS o BFS), modificato in
modo che i rami vengano attraversati solo secondo il proprio
orientamento
Grafo orientato e raggiungibilit
A
C
E
B
D
F
Da A si raggiunge {C, D, E}
Da B si raggiunge tutto il grafo
Da C si raggiunge {A, D, E}
Da D si raggiunge {A, C, E}
Da E si raggiunge {A, C, D}
Da F si raggiunge {A, C, D, E}
Un grafo orientato (o un suo componente) connesso si
definisce fortemente connesso (strongly connected) se
esiste un percorso orientato tra qualsiasi coppia ordinata
di suoi vertici
Quindi, un grafo fortemente connesso se e solo se,
per ogni coppia di suoi vertici, v e u, u raggiungibile
da v e v raggiungibile da u
Questo grafo
fortemente connesso
Esistono algoritmi che
verificano questa propriet
(attraversamenti modificati)
Grafo fortemente connesso
a
d
c
b
e
f
g
Una categoria di grafi orientati ricca di applicazioni quella
dei grafi orientati privi di cicli orientati (o aciclici), per i
quali si usa la sigla DAG (directed acyclic graph)
Possono avere cicli non orientati
Esempi
Grafo di classi e interfacce Java, con rami orientati da una super-
classe/interfaccia a una sotto-classe/interfaccia (relazioni extends
tra classi o tra interfacce) e da uninterfaccia a una classe che la
implementa (relazioni implements)
Grafo di esami da sostenere, con rami orientati da un insegnamento
x a un altro insegnamento per il quale x sia propedeutico
Pi in generale, grafo di sottoproblemi da risolvere per raggiungere un
obiettivo, con rami orientati da un sottoproblema s a un altro
sottoproblema la cui soluzione dipende dalla soluzione del
sottoproblema s
In generale, il DAG una struttura dati utile per
rappresentare relazioni di dipendenza o precedenza
Grafo orientato aciclico
Tipico problema da risolvere in un DAG: individuare un ordinamento
topologico dei suoi vertici (in generale, non unico)
Solitamente un ordinamento topologico si rappresenta assegnando a
ciascun vertice v del grafo G un numero intero positivo, index(v)
Tutti gli ordinamenti topologici hanno la seguente propriet
ramo orientato e = (u, v) G, index(u) < index(v)
Si pu dimostrare che un grafo orientato un DAG se e solo
se ha un ordinamento topologico
Quindi, un algoritmo che cerca un
ordinamento topologico effettua,
come sottoprodotto, la verifica
che il grafo su cui opera sia un DAG
Se lalgoritmo corretto e non
trova un ordinamento topologico, vuol
dire che il grafo ha almeno un ciclo orientato (cio non un DAG)
DAG e ordinamento topologico
B
A
D
C
E
1
2
3
4 5
Principale applicazione dellordinamento topologico
Individuazione di uno scheduling (pianificazione
temporale) tra attivit nel rispetto di vincoli di
precedenza/dipendenza
Esempi
Grafo di classi e interfacce Java
Si possono realizzare le classi e le interfacce seguendo un ordinamento
topologico: questo consente il loro collaudo progressivo, perch tutte le
classi e le interfacce da cui dipendono sono gi state realizzate
Grafo di esami da sostenere, con rami orientati da un insegnamento x a un
altro insegnamento per il quale x sia propedeutico
Bisogna sostenere gli esami secondo un ordinamento topologico
Grafo di sottoproblemi da risolvere per raggiungere un obiettivo, con rami
orientati da un sottoproblema s a un altro sottoproblema la cui soluzione
dipende dalla soluzione del sottoproblema s
Bisogna risolvere i sottoproblemi secondo un ordinamento topologico
DAG e ordinamento topologico
La ricerca di un ordinamento topologico (che, in generale, non unico) si pu
fare anche senza sapere a priori se il grafo sia un DAG
Se potessimo modificare il grafo, lidea sarebbe questa
Assegniamo (a caso) numeri crescenti ai vertici privi di rami entranti
che non siano ancora numerati (se non ce ne sono, il grafo non un DAG)
Eliminiamo dal grafo i rami uscenti dai vertici a cui abbiamo assegnato un
numero (rami entranti non ce ne sono)
Ripetiamo finch ci sono vertici
non numerati
DAG e ordinamento topologico
B
A
D
C
E
B
A
D
C
E
1
2
B
A
D
C
E
1
2
3
B
A
D
C
E
1
2
3
4
5
1
2
3
4
Invece di distruggere il grafo, usiamo delle etichette
Usiamo un algoritmo simile a Dijkstra, con le stesse prestazioni
Etichetta iniziale per ogni vertice: il suo grado di rami entranti
Scelta: uno dei vertici avente etichetta uguale a zero
Rilassamento: per ogni ramo uscente dal vertice scelto, decrementare
di ununit letichetta dellaltro estremo del ramo (la sua destinazione)
(Si dimostra che) Lordine in cui vengono scelti i vertici un ordinamento
topologico del grafo
(Si dimostra che) Se rimangono vertici che non sono stati numerati (e il
grafo completamente raggiungibile dai vertici iniziali, quelli che hanno
grado entrante inizialmente uguale a zero), allora non un DAG
Corollario: un grafo fortemente connesso
ciclico (tutti i vertici sono raggiungibili da
altri vertici, quindi hanno grado entrante
diverso da zero e non riesco a iniziare)
DAG e ordinamento topologico
B
A
D
C
E
1
2
3
4 5