L’algoritmo di Dijkstra risolve il problema SPP ed il problema SPT in un grafo G=(V,A), tale che (G non può contenere cicli di costo negativo).
L’algoritmo di Dijkstra si basa sul contenuto di un importante teorema di cui riportiamo di seguito l’enunciato.
Teorema. Sia G=(V,A) un grafo orientato. Sia S un sottoinsieme proprio di V, s in S e per ogni i in S, sia L[i] il costo del cammino minimo da s ad i (L[s]=0).
Sia, inoltre,
Se , allora .
L’algoritmo di Dijkstra usa un array di etichette L[n].
Durante la computazione l’insieme V è partizionato in due sottoinsiemi:
Inizialmente, solo il nodo origine s è etichettato permanentemente e la sua etichetta permanente vale 0.
Tutti gli altri nodi hanno etichetta temporanea che vale e sono memorizzati in una lista Q.
Ad ogni iterazione l’algoritmo rimuove da Q il nodo i corrispondente all’etichetta temporanea minima che diventa permanente (grazie alla validità del Teorema) e poi esplora la stella uscente FS(i) di i, al fine di eventualmente migliorare l’etichetta temporanea dei nodi adiacenti ad i.
Note.
L’inizializzazione dell’array dei predecessori e dell’array delle etichette temporanee dei nodi (loop for 2–4) richiede
Il loop while (linee 5–13) richiede e ad ogni sua iterazione l’individuazione in Q del nodo i avente etichetta minima richiede , mentre l’esplorazione di FS(i) richiede .
Ne consegue che la complessità dell’algoritmo di Dijkstra è
In letteratura esistono diverse implementazioni dell’algoritmo di Dijkstra che si differenziano tra loro per la scelta della particolare struttura dati da adoperare per rappresentare Q.
Una di esse, ad esempio, implementa Q come heap binario.
In tal caso, in fase di inizializzazione occorre costruire l’heap Q.
Ad ogni iterazione
Dunque, la complessità totale diventa
In un’altra interessante implementazione, nota come implementazione di Dial, Q è un array cha ha un numero di elementi pari al massimo numero di differenti valori che un’etichetta temporanea può assumere, cioè
Ogni entrata Q[k] è chiamata bucket ed è una lista doppiamente puntata contenente tutti i nodi la cui etichetta temporanea ha valore k.
E’ semplice verificare che l’ implementazione di Dial ha complessità pseudopolinomiale pari a
Lo spazio di memoria che essa richiede è molto grande, ma può facilmente essere ridotta a , stabilendo che un nodo j viene memorizzato nel bucket Q[k] se
1. Presentazione del Corso ed Introduzione alla Programmazione Mat...
2. Introduzione ai Problemi di PL
6. Algoritmo del Simplesso Revisionato
7. Algoritmo del Simplesso Tabellare
10. Soluzione di Problemi di PL tramite Algoritmo del Simplesso
11. Problemi di Programmazione Lineare Intera
12. PLI con matrice dei vincoli unimodulare
13. Problemi di PLI: Branch & Bound
14. Il Problema dello Zaino 0/1 e il Problema dello Zaino Frazionar...
15. Il Problema dello Zaino 0/1: un algoritmo B&B
16. Il Problema dello Zaino 0/1: un algoritmo di Programmazione Din...
17. Richiami di Teoria dei Grafi: definizioni e notazioni
18. Il Problema del Vertex Cover Minimo di un Grafo
19. Il Problema dell'Albero di Copertura Minimo (MST)
20. Il Problema dell'Albero di Copertura Minimo (MST): esempio
D. Bertsimas e J.N. Tsitsiklis, Introduction to Linear Optimization, Belmont - Massachusetts (USA), Dynamic Ideas and Athena Scientific, 2008.
M. Fischetti, Lezioni di Ricerca Operativa, Padova, Edizioni Libreria Progetto Padova, 1999.
S. Martello, Fondamenti di Ricerca Operativa L-A, Bologna, Società Editrice Esculapio, 2004.
S. Martello, Ricerca Operativa LS, Bologna, Società Editrice Esculapio, 2004.
Dispense del Corso di Ricerca Operativa presso l'Università degli Studi di Pisa.
Dispense ed Appunti del Corso prodotte da Paola Festa.