DAA - Percorsi più brevi

Algoritmo di Dijkstra

L'algoritmo di Dijkstra risolve il problema dei cammini minimi da una sola sorgente su un grafo ponderato diretto G = (V, E) , dove tutti gli archi sono non negativi (cioè, w (u, v) ≥ 0 per ogni arco (u, v ) Є E ).

Nel seguente algoritmo, useremo una funzione Extract-Min(), che estrae il nodo con la chiave più piccola.

Algorithm: Dijkstra’s-Algorithm (G, w, s) 
for each vertex v Є G.V  
   v.d := ∞ 
   v.∏ := NIL 
s.d := 0 
S := Ф 
Q := G.V 
while Q ≠ Ф 
   u := Extract-Min (Q) 
   S := S U {u} 
   for each vertex v Є G.adj[u] 
      if v.d > u.d + w(u, v) 
         v.d := u.d + w(u, v) 
         v.∏ := u

Analisi

La complessità di questo algoritmo dipende completamente dall'implementazione della funzione Extract-Min. Se la funzione di estrazione min è implementata utilizzando la ricerca lineare, la complessità di questo algoritmo èO(V2 + E).

In questo algoritmo, se usiamo min-heap su cui Extract-Min() funziona per restituire il nodo da Q con la chiave più piccola, la complessità di questo algoritmo può essere ulteriormente ridotta.

Esempio

Consideriamo il vertice 1 e 9rispettivamente come vertice iniziale e vertice di destinazione. Inizialmente, tutti i vertici tranne il vertice iniziale sono contrassegnati da ∞ e il vertice iniziale è contrassegnato da0.

Vertice Iniziale Passaggio 1 V 1 Passaggio 2 V 3 Passaggio 3 V 2 Passaggio 4 V 4 Passaggio 5 V 5 Passaggio 6 V 7 Passaggio 7 V 8 Passaggio 8 V 6
1 0 0 0 0 0 0 0 0 0
2 5 4 4 4 4 4 4 4
3 2 2 2 2 2 2 2 2
4 7 7 7 7 7 7
5 11 9 9 9 9 9
6 17 17 16 16
7 11 11 11 11 11 11 11
8 16 13 13 13
9 20

Quindi, la distanza minima del vertice 9 dal vertice 1 è 20. E il percorso è

1 → 3 → 7 → 8 → 6 → 9

Questo percorso è determinato in base alle informazioni sul predecessore.

Algoritmo di Bellman Ford

Questo algoritmo risolve il problema del percorso minimo della singola sorgente di un grafo orientato G = (V, E)in cui i pesi dei bordi possono essere negativi. Inoltre, questo algoritmo può essere applicato per trovare il percorso più breve, se non esiste alcun ciclo ponderato negativo.

Algorithm: Bellman-Ford-Algorithm (G, w, s) 
for each vertex v Є G.V  
   v.d := ∞ 
   v.∏ := NIL 
s.d := 0 
for i = 1 to |G.V| - 1 
   for each edge (u, v) Є G.E 
      if v.d > u.d + w(u, v) 
         v.d := u.d +w(u, v) 
         v.∏ := u 
for each edge (u, v) Є G.E 
   if v.d > u.d + w(u, v) 
      return FALSE 
return TRUE

Analisi

Il primo for loop viene utilizzato per l'inizializzazione, che viene eseguita in O(V)volte. Il prossimofor il ciclo viene eseguito |V - 1| passa oltre i bordi, che prendeO(E) volte.

Quindi, l'algoritmo Bellman-Ford viene eseguito O(V, E) tempo.

Esempio

L'esempio seguente mostra passo dopo passo come funziona l'algoritmo Bellman-Ford. Questo grafico ha un margine negativo ma non ha alcun ciclo negativo, quindi il problema può essere risolto utilizzando questa tecnica.

Al momento dell'inizializzazione, tutti i vertici tranne la sorgente sono contrassegnati da ∞ e la sorgente è contrassegnata da 0.

Nella prima fase, tutti i vertici raggiungibili dalla sorgente vengono aggiornati con un costo minimo. Quindi, verticia e h vengono aggiornati.

Nella fase successiva, vertici a, b, f e e vengono aggiornati.

Seguendo la stessa logica, in questo passaggio vertici b, f, c e g vengono aggiornati.

Qui, vertici c e d vengono aggiornati.

Quindi, la distanza minima tra i vertici s e vertice d è 20.

In base alle informazioni sul predecessore, il percorso è s → h → e → g → c → d