Sei sulla pagina 1di 8

Descrizione del problema

Traccia assegnata:
Stai visitando una nazione estremamente tecnologica e vuoi visitare n delle sue pi importanti citt,
numerate da 0 a n-1. Inizialmente ti trovi nella citt K.
Hai affittato una macchina che dotata delle pi sofisticate dotazioni tecnologiche, tra cui anche un
dispositivo di teletrasporto.
Questo dispositivo pu teletrasportarti allistante insieme alla tua macchina in unaltra citt di tua
scelta.
C un unico problema: il dispositivo di teletrasporto funziona soltanto se in precedenza hai gi
visitato nel tuo tour la citt in cui ti vuoi teletrasportare.
Hai a disposizione una mappa della nazione con le n citt che vuoi visitare, contenente le strade
(unidirezionali) tra queste citt, e i tempi di percorrenza di queste strade.
Il tuo obiettivo quello di trovare il minimo tempo possibile per visitare tutte le n citt.

Spiegazione traccia assegnata:


Il problema presentato sotto forma di un grafo orientato G(V,E):
Un grafo orientato (o diretto) G(V,E) consiste in un insieme V di nodi ed un insieme E di coppie di
nodi (u,v) detti archi: ogni arco connette il nodo u al nodo v ma non viceversa.
Il problema si pu risolvere trovando il minimo albero ricoprente di G(V,E) .
Albero:
Un albero un grafo T(W,F) nel quale due nodi siano connessi tramite uno ed un solo cammino.
T(W,F) un albero di G(V,E) se W un sottoinsieme di V ed F un sottoinsieme di E.
Albero Ricoprente:
Dato un grafo G(V,E) connesso, un albero ricoprente di G un sottografo T di G tale che:
1. T un albero
2. T contiene tutti i vertici di G
Minimo Albero Ricoprente:
Dato un grafo G(V,E) connesso e pesato sugli archi, un minimo albero ricoprente di G un albero
ricoprente di G di costo minimo.

Gli algoritmi visti a lezione per risolvere il problema del Minimo Albero Ricoprente (MST) sono:

Algoritmo di Prim
Algoritmo di Kruskal
Algoritmo di Boruvka

Ma nessuno di questi algoritmi pu essere usato per risolvere il nostro problema, dato che si
occupano trovare il l MST per grafi non orientati, mentre il il grafo presentato nell traccia un
grafo orientato.
Per trovare lMST di un grafo orientato useremo lalgoritmo di Edmonds (chiamato anche
algoritmo di Chu-Liu-Edmonds).
Questo algorimto stato sviluppato in modo indipendente prima da Yoeng-chin Chu e Tseng-hong
Liu (nel 1965) e poi da Jack Edmonds (nel 1967), il quale ne ha anche fornito una dimostrazione
della sua correttezza.

Descrizione dellAlgoritmo
Lalgoritmo lavora su grafi diretti connessi, aventi archi con peso maggiore od uguale a zero
Iniziamo eliminando tutti gli archi entranti la radice.
Per ogni vertice v (tranne la radice) sia Sv linsieme degli archi entranti in v. Sia vj larco di costo
minimo entrante in v.
Si riduca il peso di tutti gli archi in Sv del peso di vj. Ora avremo per ogni nodo, tranne la radice,
almeno un arco entrante di costo 0 (larco vj). Prendendo tutti gli archi di costo 0 si verificano due
possibilit:
1. Gli archi di costo 0 formano un albero di costo 0 .
Oppure
2. Esiste almeno un ciclo di costo 0.
Nel primo caso lalgoritmo finito e restituisce il Minimo Albero Ricoprente.
Nel secondo caso contraiamo i nodi del ciclo in una una struttura che chiameremo Supernodo. Il
Supernodo ha come archi entranti tutti gli archi non facenti parte del ciclo ed entranti nei nodi del
ciclo, e come archi uscenti tutti gli archi non facenti parte del ciclo ed uscenti dai nodi del ciclo.
Dopo ci il procedimento viene ripetuto finch non esistono pi cicli a costo 0.
A questo punto avremo un albero ricoprente composto dai nodi che non facevano parte di nessun
ciclo a costo 0 e dai supernodi.

Si espandono i supernodi e, per ognuno, si elimina larco del ciclo incidente su un nodo con un arco
incidente esterno al ciclo. Lalbero risultante sar un Minimo Albero Ricoprente.

Esempio:
Prendiamo ad esempio un grafo G, con radice r

Ecco come risulta G dopo aver effettuato la riduzione dei pesi degli archi entranti ad ogni nodo

In rosso sono segnati tutti gli archi di costo 0 che andranno a formare , in questo caso, un ciclo.

Ecco come risulta il grafo G dopo la compressione dei nodi a, b, c, d nel supernodo

Viene di nuovo effettuata la riduzione del peso degli archi entranti ad ogni nodo

In rosso sono segnati tutti gli archi di costo zero. A questo punto abbiamo un albero di costo 0.

Viene espanso il supernodo (abcd) e viene eliminato larco del ciclo che incide sul nodo con due
archi entranti

Abbiamo ottenuto lMST

Implementazione dellalgoritmo
Dato che lalgoritmo di Edmonds applicabile solo su grafi connessi alla radice allinizio viene
eseguita una visita DFS per verificare la connessione.
Se la visita rileva che il grafo non connesso il resto dellalgoritmo non viene eseguito.
Altrimenti vengono cancellati gli eventuali archi entranti nella radice e viene effettuato il
ripesamento degli archi entranti in ogni nodo:
Per semplificare i passi successivi lazione di ripesamento viene effettuata su un grafo copia(1)
creato eseguendo la funzione deepcopy sul grafo originario.

Per ogni nodo viene cercato larco entrante di peso minimo e sottratto il suo peso ad ogni
arco entrante nel nodo

A questo punto viene eseguita la funzione trovaciclo:

Viene creato un nuovo grafo(2), copia del primo grafo copia(1), in cui vengono cancellati
tutti gli archi con peso diverso da zero. Questo grafo copia(2) utilizzato solamente in
questo modulo e nessun altra modifica viene eseguita.
Viene eseguita una visita del grafo in modo da verificare la presenza di un eventuale ciclo
(che sar per forza a costo 0).
Se verificata la presenza di un ciclo, la funzione ritorna una lista contenente i nomi dei nodi
che compongono il ciclo.

Se non viene trovato nessun ciclo lalgoritmo esegue il modulo ricostruzione_grafo.


Altrimenti viene creato il supernodo usando la funzione crea del modulo creazione_supernodo:

Viene creato un supernodo a cui sono aggiunti i nomi dei nodi del ciclo. Questo supernodo
sar aggiunto alla lista_supernodi nel modulo algoritmo subito dopo la fine della funzione
crea.
Vengono cancellati tutti gli archi facenti parte del ciclo.
Vengono deviati tutti gli archi entranti od uscenti dai nodi del ciclo sul primo nodo di
questultimo. E il primo nodo presente nella lista che viene creata dalla funzione trovaciclo.
Viene selezionato larco con peso minimo e tutti gli altri sono cancellati.

Questultimo passaggio viene eseguito pi volte finch la funzione trova ciclo non restituisce
nessun ciclo.
Successivamente viene eseguito il modulo ricostruzione_grafo:

La funzione elimina nel grafo copia(1) (contente i supernodi) tutti gli archi con peso diverso

da zero.
Controlla che ogni nodo abbia al pi un arco entrante. Se non cos cancella tutti gli archi
entranti nel nodo in questione tranne uno.
Successivamente crea un nuovo grafo in cui verr costruito lMST.
In questo grafo vengono prima inseriti tutti i nodi del grafo originario,
Poi vengono utilizzati i supernodi per aggiungere gli archi che compongono i cicli a costo
zero
Successivamente per ogni ciclo si sceglie larco entrante nel ciclo la quale differenza di peso
con larco entrante nello stesso nodo (il quale ha sicuramente peso minore) sia minima.
Viene aggiunto questo arco al grafo e cancellante laltro arco entrante nello stesso nodo.
Viene completato il grafo aggiungendo gli archi entranti in tutti i nodi che non facevano
parte dei cicli
( in tutti questi passaggi si usa come peso il peso originario dellarco, preso dal grafo iniziale)
A questo punto viene effettuata la somma dei pesi degli archi e stampata.

Strutture Dati Particolari


Lalgoritmo fa uso di una particolare struttura dati, la struttura grafo, e le strutture a lei subordinate:
i nodi, gli archi ed i supernodi.
Struttura Grafo:
La struttura grafo una classe contenente gli oggetti Node , Arch e Supernode
Loggetto Node possiede tre variabili: il nome(name), la lista degli archi entranti (archsIn) e la lista
degli archi uscenti (archsOut).
Loggetto Arch possiede tre variabili: il nome del nodo testa dellarco (nodeNameTo), il nome del
nodo coda dellarco (nodeNameFrom) ed il peso dellarco (weight).
Loggetto Supernode possiede una sola variabile: la lista dei nodi componenti il supernodo.
Complessivamente il grafo rappresentato tramite liste di adiacenza: ogni nodo contiene una lista di
tutti i nodi a cui adiacente. Come unica differenza da una lista di adiacenza standard ogni nodo
contiene anche una lista dei nodi a cui adiacente.

Tempo di esecuzione ed occupazione di memoria


Tempo
Connessione O(V)
Ripesamento O(EV)
Ciclo O(V+E)
Creazione Supernodo O(V+E)
Ricostruzione O(EV)
Il tempo di esecuzione limitato inferiormente dai moduli ripesamento e ricostruzione_grafo, i
qulai hanno tempo di esecuzione O(EV).
Quindi il tempo totale di esecuzione dellalgoritmo per un grafo G(V,E) O(EV)
Spazio
Connessione O(V)
Ripesamento grafo copia (1) + O(V)
Ciclo grafo copia(2) + O(V)
Creazione Supernodo O(V)
Ricostruzione grafo temporaneo (minore dell originale)

Lo spazio occupato in funzione del grafo originario e delle sue copie. Siccome ogni nodo contiene
una lista degli archi uscenti ed entranti ogni arco rappresentato due volte, quindi la lunghezza
complessiva delle liste 2E.
In totale lo spazio utilizzato O(V+E).