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 = ∞ .MMio , ji → jMio , j= ∞
L'algoritmo ha passi. Nel passaggio k dell'algoritmo, per ogni coppia di nodi i , j impostiamoVKio , j
Mio , j← min { Mio , j, Mio , 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 MMio , k= ∞Mk , j= ∞de gio n( k ) ⋅ de go u t( k )de gio n( k )de go u t( 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)