Qual è l'algoritmo più veloce per trovare tutti i percorsi più brevi in ​​un grafico sparso?


24

In un grafico non ponderato e non orientato con vertici e bordi tali che , qual è il modo più veloce per trovare tutti i percorsi più brevi in ​​un grafico? Può essere fatto più velocemente di Floyd-Warshall che è ma molto veloce per iterazione?E 2 V > E O ( V 3 )VE2V>EO(V3)

Che ne dici se il grafico è ponderato?

Risposte:


32

Poiché si tratta di un grafico non ponderato, è possibile eseguire una Breadth First Search (BFS) da ogni vertice v nel grafico. Ogni serie di BFS fornisce le distanze (e i percorsi) più brevi dal vertice iniziale a ogni altro vertice. La complessità temporale per un BFS è O(V+E)=O(V) poiché E=O(V) nel tuo grafico sparso. Eseguendolo V volte ti dà una complessità temporale O(V2) .

Per un grafico diretto ponderato, l' algoritmo di Johnson come suggerito da Yuval è il più veloce per i grafici sparsi. Ci vuole O(V2logV+VE) che nel tuo caso risulta essere O(V2logV) . Per un grafico non orientato ponderato, è possibile eseguire l'algoritmo di Dijkstrada ciascun nodo o sostituire ciascun bordo non diretto con due bordi diretti opposti ed eseguire l'algoritmo di Johnson. Entrambi questi daranno gli stessi tempi aysmptotic dell'algoritmo di Johnson sopra per il tuo caso scarso. Si noti inoltre che l'approccio BFS che cito sopra funziona sia per i grafici diretti che non indirizzati.



7

Puoi provare a creare una versione di Floyd-Warshall più veloce su matrici sparse.

Innanzitutto, ricordiamo cosa fa questo algoritmo:

Lascia che sia una matrice di distanze. All'inizio dell'algoritmo M i , j è il peso del bordo i j . Se questo bordo non esiste, allora M i , j = .MMi,jijMi,j=

L'algoritmo ha passi. Nel passaggio k dell'algoritmo, per ogni coppia di nodi i , j impostiamoVki,j

Mi,jmin{Mi,j,Mi,k+Mk,j}.

Chiaramente se o non è necessario eseguire alcun aggiornamento. Quindi, nei primi passi dell'algoritmo, dobbiamo solo eseguire approssimativamente confronti dove e denotano il numero di fronti in entrata e in uscita del nodo -th rispettivamente. Man mano che l'algoritmo avanza, vengono riempite sempre più voci della matricePertanto, gli ultimi passaggi potrebbero richiedere molto più tempo.M k , j = d e g i n ( k ) d e g o u t ( k ) d e g i n ( k ) d e g o u t ( k ) k MMi,k=Mk,j=degin(k)degout(k)degin(k)degout(k)kM

Nota che abbiamo bisogno di un modo efficiente per iterare solo su celle non infinite nella -esima riga e colonna della matrice. Questo può essere fatto mantenendo una serie di fronti in entrata e in uscita per ogni nodo.k

Sembra che i primi passi dell'algoritmo possano trarre grandi benefici dalla scarsità. Ad esempio, un grafico costruito casualmente con suggerisce che la prima iterazione ( ) è solo passi. Se il grafico viene suddiviso in molti componenti collegati, la matrice rimarrebbe relativamente scarsa in tutto l'algoritmo e il tempo di esecuzione totale potrebbe essere basso quanto . D'altra parte, se il grafico contiene solo un componente collegato, allora l'ultima iterazioneè previsto che esegua passi. In questo caso il tempo di esecuzione totale potrebbe essere . Grande quanto la versione non sparsa.k = 0 O ( 1 ) M O ( V ) k = | V | O ( V 2 ) O ( V 3 )E=O(V)k=0O(1)MO(V)k=|V|O(V2)O(V3)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.