Problemi che richiedono di trovare il cammino
di costo minimo fra una o più coppie di nodi
di un grafo sono tra i più importanti nelle applicazioni pratiche.
Vogliamo qui dare una panoramica introduttiva
di sapore algoritmico e prettamente combinatorio.
Quando il costo di ogni arco è positivo
Dato un digrafo pesato D
ed un nodo sorgente s di Dvogliamo trovare per ogni nodo
un cammino che vada da s a v di costo minimo.
(Il costo di un cammino è dato dalla somma dei pesi
degli archi nel cammino).
Incominciamo con alcune facili osservazioni:
Supponiamo di essere interessati a tutti i cammini minimi da s ad ogni altro nodo. Potrebbe sembrare che in generale si andranno ad utilizzare svariati archi del grafo in esame. Invece è sempre possibile limitarsi a |V(D)|-1 archi:
In virtù di questa osservazione ci è possibile
ritornare la soluzione ottima in spazio
.
L'idea è la seguente:
per ogni nodo v ritorno un padre ossia il penultimo nodo in un qualche cammino
ottimo da s a v.
Gli archi del cammino ottimo da s a v sono
quindi prodotti da una procedura PATH
qui sopra espressa in pseudocodice.
Pesi Tutti unitari: Breath First Search
Dato un digrafo D ed un nodo sorgente s di Dvogliamo trovare per ogni nodo
un cammino che vada da s a v utilizzando il minor
numero possibile di archi.
Ci stiamo cioè restringendo
al caso di cardinalità,
quando tutti i pesi sono unitari.
In questo caso abbiamo un`algoritmo molto efficiente (complessità ): la famigerata Breath First Search (BFS).
Pesi Tutti Positivi: l'algoritmo Dijkstra
Ritorniamo ora ad un caso più generale: quello pesato.
Assumeremo tuttavia l'ipotesi semplificatrice che tutti
i pesi siano non-negativi.
Nell'algoritmo che proponiamo le etichette
che diamo ai nodi non sono sempre permanenti
ossia ci riserviamo di trovare cammini migliori
nel proseguio dell'algoritmo.
Piú precisamente associamo un valore booleano
f(v) ad ogni nodo.
Quando f(v) é Falso é ancora possibile
che
diminuisca.
Quando f(v) é Vero il cammino
ottimo da s a v è già stato trovato.
Tracciamo il comportamento dell' Algoritmo Dijkstra nel seguente esempio.
|
Quando non ci sono cicli negativi
Quando siamo in presenza di archi di costo negativo il problema si complica notevolmente. Tanto è vero che se non poniamo restrizione alcuna il problema di trovare un cammino semplice (nessun arco ripetuto) ottimo diviene -completo in quanto contiene come caso particolare il problema del cammino amiltoniano. Se non richiediamo che il cammino sia semplice allora il problema diviene illimitato se e solo se siamo in presenza di cicli negativi. Si adotta pertanto la seguente:
In virtù di tale assunzione
risulta poi inessenziale richiedere
o meno che i cammini siano semplici
dacché ogni cammino di peso minimo
eviterá di sua sponte di ciclare.
Sottolineiamo ora una questione importante: la riduzione di cui al Fatto 1 non è più applicabile poichè un arco non orientato negativo darebbe automaticamente luogo ad un ciclo negativo. Pertanto ci limiteremo ai soli digrafi.
Ritornando invece al caso più semplice dei digrafi abbiamo l'algoritmo di Ford la cui complessità è .
Suggerimento: Si dimostri per induzione che a completamento del ciclo a conteggio per i=k la variabile esprime il minimo costo di un cammino da s a v in al più k archi.
14 Maggio 1998 |
© Dipartimento di Matematica - Università di Trento |