You are on page 1of 8

Analisi e implementazione dellalgoritmo di

Dijkstra (Parte 1)
Algoritmicamente
August 1, 2009
http://algoritmicamente.wordpress.com/

Concetti fondamentali

Definizione 1 Un grafo `e un insieme di vertici pi`


u un insieme di archi
che connettono coppie di vertici distinti.
Una definzione pi`
u formale `e comunque necessaria in quanto allinterno di tale
articolo essa sar`a spesso utilizzata:
Definizione 1.1 Si dice grafo G una coppia ordina G=(V,E) di insiemi,
dove V `e linsieme dei vertici ed E linsieme degli archi .
Definizione 1.2 Un vertice `e un punto terminale oppure un punto di
intersezione di un grafo.
Definizione 1.3 Un arco `e una connessione tra due vertici. Esso viene
indicato con la coppia ( i,j), dove i indica il vertice da cui parte larco (testa) e
j indica il vertice in cui arriva (coda).
Per dare unidea pi`
u concreta di un grafo, viene mostrato un esempio di esso:

Come si pu`
o notare linsieme dei vertici V = {v1 , v2 , v3 , v4 , v5 , v6 } mentre linsieme
degli archi `e dato da tutte le coppie di vertici che vengono connessi tra loro, in
questo caso:
G = {{v1 , v2 } , {v1 , v4 } , {v1 , v6 } , {v3 , v6 } , {v5 , v2 } , {v5 , v6 } , {v2 , v4 } , {v4 , v6 } , {v5 , v6 }}.
Spesso (come nel caso trattato) ad ogni vertice o ad ogni arco viene associato
un peso ossia un valore numerico che indica la distanza che intercorre da due
vertici. Tale tipo di grafo prende il nome di grafo pesato del quale viene data
una definizione pi`
u formale.
Definizione 1.4 Un grafo pesato G `e definito come una terna G = ( V,E,P).
Dove V ed E indicano il grafo G = ( V,E) e P indica una generica funzione
che ad ogni vertice o ad ogni arco associa un valore numerico n [, +].
Definizione 1.5 Un cammino (p) in un grafo `e una sequenza di vertici
nei quali ogni vertice successivo `e adiacente al precedente nel cammino.
Definizione 1.5.1 Un cammino semplice, `e un cammino dove tutti i
vertici sono distinti.
Definizione 1.5.2 Un ciclo `e un cammino semplice, eccetto che il vertice
iniziale e finale rimangono invariati.

fig. 2 Grafo pesato

fig. 3 Possibile cammino di un grafo

Nella figura 3 `e possibile vedere il cammino p = {v1 , v2 , v5 , v3 , v6 }

Cammini minimi

Lanalisi dei cammini minimi `e il cuore di tale articolo, infatti lalgorito di Dijkstra ha come scopo quello di trovare il cammino minimo allinterno di un grafo.
Prima di tutto bisogna far chiarimento su cosa sia un cammino minimo
Definizione 2 Dato un grafo G=( V,E,P) ed un cammino p = {v1 , v2 , ..., vn }
il peso di un cammino (p) `e la somma dei pesi degli archi che compongono
tale cammino.

Dalla figura risulta che il peso del cammino in rosso `e dato da:
(p) = (1 + 5 + 21 + 3) = 30.
Detto ci`
o `e possibile ora definire il cammino minimo di un generico grafo G.
Definizione 2.1 Dato un grafo G = ( V,E,P) il cammino minimo di tale
grafo `e il pi`
u piccolo dei (pn ), dove pi 1 i n `e un generico cammino del
grafo G.
Grazie a tale definizione appare pi`
u chiaro lo scopo dellalgoritmo di Dijkstra,
infatti mediante esso possiamo trovare IL cammino minimo allinterno di un
grafo pesato G.
Seguono dunque alcuni esempi per mostrare il cammino minimo allinterno di
un grafo:

fig. 4 Cammino minimo corretto

fig. 5 Cammino minimo scorretto

Come si pu`
o dunque notare dalle due figure, il cammino minimo (per arrivare
dal vertice 1 al vertice 3) non `e quello pi`
u breve cio`e quello che percorre meno
archi, ma, come detto nella definizione, `e quello la cui somma dei pesi degli archi
`e minima.
Tale problema non `e banale in quanto vi `e unimportante osservazione da fare:
Come si pu`
o notare in entrambe le figure (fig.4, fig5) il cammino minimo non
inizia affatto con larco di peso minore, anzi, in questo caso il cammino minimo
`e quello che ha come arco di partenza, quello con il peso maggiore (gli altri sono
E1 = {v1 , v6 } il quale ha peso 2, e E2 = {v1 , v4 } il quale ha peso 1). Ci`o ci da la
dimostrazione che il cammino minimo `e dato da una somma, e in quanto somma
si deve tener conto degli addendi che la compongono (in questo caso i pesi). Inoltre, dalla definizione 1.4 si evince che i pesi possono anche essere negativi,
dunque per quanto possa essere grande il peso del primo arco di un percorso, il
peso di un cammino potr`
a essere diminuito a causa di un cammino di valore
negativo.

Algoritmo di Dijkstra

Lalgoritmo di Dijkstra permette di poter calcolare i cammini minimi allinterno


di un grafo, la forza di tale algoritmo `e la semplicit`a del codice e soprattutto
la sua efficienza, infatti la complessit`a nel caso peggiore di tale algoritmo `e :
O(|E|+|V|log |V |) .
Esso possiede inoltre delle propriet`
a particolari :
Propriet`
a 3
Lalgoritmo di Dijkstra risolve i problemi di cammino minimo,da un vertice di partenza ad un vertice di arrivo, nei grafi che non hanno
pesi negativi.
Propriet`
a 3.1
Con Lalgoritmo di Dijkstra possiano trovare ogni SPT in
una grafo denso in un tempo lineare.
La propriet`
a 3.1 viene data solo a scopo informativo, non `e interesse di tale
articolo trattare argomenti non inerenti con lanalisi di tale algoritmo, mentre
la propriet`
a 3 pu`
o essere dimostrata, tale dimostrazione verr`a trattata in seguito.
Il funzionamento `e molto semplice, dato un grafo e un vertice di partenza,
lalgoritmo mostra tutti i cammini minimi per raggiungere gli altri nodi, per
poter meglio comprendere tale algoritmo viene mostrato inizialmente il suo pseudocodice completo.
function Dijkstra(Graph, source):
for each vertex v in Graph:
dist[v ] := infinity
previous[v ] := undefined
dist[source] := 0
Q := the set of all nodes in Graph
while Q is not empty:
u := vertex in Q with smallest dist[] 8
if dist[u] = infinity:9
break 10
remove u from Q 11
for each neighbor v of u: 12
alt := dist[u] + dist between(u, v ) 13
if alt < dist[v ]: 14
dist[v ] := alt 15
previous[v ] := u 16
return previous
La I riga non `e altro che il prototipo della funzione, la quale (come gi`a detto)
accetta in input un grafo e un vertice sorgente.
Possiamo dividere tale algoritmo in due parti, linizializzazione del grafo dato
in input, e lalgoritmo vero e proprio.
4

Per quanto riguarda linizializzazione, essa `e effettuata dalle righe 2,3,4,5,6 nelle
quali vengono effettuate le inizializzazioni per tutti i nodi, pi`
u nello specifico,
le righe 3,4 settano le distanze dal vertice sorgente agli altri nodi a , la riga
5 setta la distanza del vertice sorgente a 0, e infine la riga 6 crea linsieme Q il
quale contiene tutti i nodi del grafo dato in input. Per chiarire meglio quanto
mostriamo un esempio.

fig. 6 Grafo dato in input

fig. 7 Grafo inzializzato

Lesempio mostrato accetta in input il grafo di fig. 6 e si prende come vertice sorgente v1. Le righe 3,4, come gi`a detto, settano le distanze di tutti i
vertici al vertice sorgente ad , tale distanza viene indicata ponendo vicino al
vertice interessato il suo valore, mentre la riga 5 setta la distanza del vertice
sorgente a 0. Infine vi `e la riga 6, la quale crea linsieme di tutti i vertici del
grafo Q, nel caso dai noi analizzato, al momento dellinizializzazione, linsieme
Q = {v1 , v2 , v3 , v4 , v5 , v6 }.
La seconda parte dellalgoritmo analizza il grafo per estrarne i cammini minimi,
essa va dalla riga 7 alla riga 16.
Possiamo subito notare che essa `e composta da un ciclo principale (while Q is
not empty:) dal quale poi si diramano gli altri cicli, tale ciclo termina ovviamente quanto linsieme Q `e vuoto.
La riga 8 prende dallinsieme Q il vertice che ha distanza minore, poiche tutti
i vertici eccetto v 1 hanno distanza infinita, verr`a selezionato v1 dallinsieme Q.
La riga 9 consiste in un if, il quale in tal caso non verr`a preso in considerazione
in quanto dist[v 1 ] = 0 6= . La riga 11 eliminer`
a in vertice v 1 dallinsieme Q
il quale ora diventer`
a Q = {v2 , v3 , v4 , v5 , v6 }. La riga 12 da origine ad un altro
ciclo, il quale analizza i pesi degli archi che connettono i vertici, tale ciclo prende
in analisi tutti i vertici che sono collegati direttamente a v 1 e ne analizza il peso
degli archi che li uniscono, viene quindi preso in considerazione v 2 il quale ha
una distanza (peso dellarco) 3 con v 1 , a tal proposito nella riga 13 viene creata
una variabile temporale alt la quale sommer`a il peso dellarco che unisce i vertici
con la distanza del vertice preso in considerazione poich`e la distanza {v 1 v,2 } =
3, e poich`e v1 ha in origine distanza = 0, alt = 0 + 3 = 3. Una volta calcolata
tale distanza, se tale distanza `e minore di quella presente nel vertice vicino a

v1 (riga 14) cio`e la distanza di v 2 allora il vertice v2 assume distanza uguale ad


alt (riga 15), dunque poiche alt < v 2 = , allora v 2 = alt = 3, nella riga 16
viene creato un array nel quale viene aggiunto il vertice v2 e cos` via per gli altri
vertici vicino ad v. Per chiarire le idee viene dato un esempio pratico di quanto
detto.

fig. 8 v1 viene preso dallinsieme Q

fig. 9 uno dei vicini di v1 viene selezionato

Viene selezionato v 1 perch`e dellinsieme Q esso `e quello che ha come distanza


minore (8) e viene tolto dallinsieme Q (11), viene poi selezionato un vicino di
v1 (12), in questo caso v2 , e poich`e 0+3 = 3 < (13,14), la sua distanza viene
posta uguale a 3 (15), viene aggiunto v2 allarray previous. Poiche v1 ha ancora
altri vicini, vengono selezionati anchessi nel for dunque avremo:

fig. 10 Completamente del ciclo for

Anche gli altri vertici vicini a v 1 vengono selezionati e viene calcolata la distanza
mediante lanalisi dei pesi degli archi che li uniscono.
Una volta effettuata tale operazione, il processo inizia nuovamente, il ciclo while

esegue unaltra iterazione e si passa alla linea 8, la quale scegliera il vertice con
la distanza pi`
u piccolo allinterno dellinsieme Q, `e da ricordare che la linea 11
aveva modificato il contenuto di Q, dunque ora verr`a selezionato come vertice
da analizzare, v 4 , poich`e esso ha la distanza minore tra tutti i vertici di Q. Le
linee 9,10 anche in questo caso non vengono prese in cosiderazione poich`e v 4
= 1 6= , dunque la linea 11 eliminera lelemento v4 dallinsieme Q, il quale
ora risulta essere composto da Q = {v 2 , v3 , v5 , v6 }. Una volta effettuata tale
operazione si entra nel ciclo for, il quale andra ad analizzare (come gi`a visto
per v1 ) tutti i vertici ad esso collegati, nellesempio mostrato lunico ad essere
vicino a v 4 `e v 6 , la riga 13 crea la variabile alt = 1 + 13 = 14, la riga 14 indica
che se la distanza di v6 > alt allora tale distanza deve essere sovrascritta con
il valore di alt, dunque poich`e 30 > 14 ne segue che il valore delle distanza di
v6 , viene settato a 14 (riga 15), infine la riga 16 aggiunge allarray il vertice v 4 ,
il quale conter`
a ora previous[] = {v 1 , v4 }, viene mostrato graficamente quanto
descritto.

fig. 11 v 4 `
e il vertice con distanza minore

fig. 12 viene calcolata la distanza di v6

Come si pu`
o notare dalla fig. 11 tra tutti i vertici, v 4 `e quello con distanza
minore, e poich`e esso ha come unico vicino v 6 , verr`a calcolata la sua distanza
basandosi sul peso dellarco che li unisce, poiche tale distanza `e uguale a 14,
mentre la distanza precedente `e uguale a 30, tale distanza viene aggiornata
mettendo il valore minore dei due.
Tale processo continua per tutti i vertici rimanenti fino a quando essi non verranno esaminati tutti, cio`e quando linsieme Q che contiene tutti i vertici `e vuolo
Q = {}. Alla fine di tale processo il grafo apparir`a come in figura.

fig. 13 fine dellalgoritmo con le distanza minime

You might also like