The Floyd-Warshall algoritmus , pojmenované po svých tvůrcích Robert Floyd a Stephen Warshall , je základním algoritmem v informatice a teorii grafů. Slouží k nalezení nejkratších cest mezi všemi dvojicemi uzlů ve váženém grafu. Tento algoritmus je vysoce účinný a dokáže zpracovat grafy s oběma pozitivní a n egativní závaží hran , což z něj činí všestranný nástroj pro řešení široké škály problémů se sítí a konektivitou.
Obsah
- Algoritmus Floyda Warshalla
- Idea algoritmu Floyd Warshall
- Floyd Warshall Algorithm Algorithm
- Pseudokód algoritmu Floyda Warshalla
- Ilustrace Floyd Warshall Algorithm
- Analýza složitosti Floyd Warshall Algorithm
- Proč je Floyd-Warshall Algorithm lepší pro husté grafy a ne pro řídké grafy?
- Důležité otázky k rozhovoru týkající se Floyd-Warshall
- Reálné aplikace Floyd-Warshallova algoritmu

Algoritmus Floyda Warshalla:
The Algoritmus Floyda Warshalla je na rozdíl od algoritmu nejkratší cesty všech párů Dijkstra a Bellman Ford což jsou jednozdrojové algoritmy nejkratší cesty. Tento algoritmus funguje pro oba režírovaný a neorientovaný vážený grafy. Ale nefunguje to pro grafy se zápornými cykly (kde je součet hran v cyklu záporný). Následuje Dynamické programování přístup ke kontrole každé možné cesty procházející každým možným uzlem, aby se vypočítala nejkratší vzdálenost mezi každou dvojicí uzlů.
misi nemožné všechny filmy
Nápad za algoritmem Floyda Warshalla:
Předpokládejme, že máme graf G[][] s V vrcholy z 1 na N . Nyní musíme vyhodnotit a nejkratšíPathMatrix[][] kde s hortestPathMatrix[i][j] představuje nejkratší cestu mezi vrcholy i a j .
Jednoznačně nejkratší cesta mezi nimi i na j bude mít nějaké k počet mezilehlých uzlů. Myšlenkou algoritmu floyd warshall je ošetřit každý vrchol 1 na N jako mezilehlý uzel jeden po druhém.
Následující obrázek ukazuje výše uvedenou optimální vlastnost substruktury v algoritmu floyd warshall:
Algoritmus Floyd Warshall Algorithm:
- Jako první krok inicializujte matici řešení stejnou jako vstupní matici grafu.
- Potom aktualizujte matici řešení tím, že všechny vrcholy budete považovat za mezilehlý vrchol.
- Cílem je vybrat všechny vrcholy jeden po druhém a aktualizovat všechny nejkratší cesty, které zahrnují vybraný vrchol jako mezilehlý vrchol v nejkratší cestě.
- Když vybereme číslo vrcholu k jako mezilehlý vrchol jsme již uvažovali vrcholy {0, 1, 2, .. k-1} jako mezilehlé vrcholy.
- Za každý pár (i, j) u zdrojových a cílových vrcholů existují dva možné případy.
- k není mezilehlý vrchol v nejkratší cestě od i na j . Udržujeme hodnotu dist[i][j] jak to je.
- k je mezilehlý vrchol v nejkratší cestě od i na j . Aktualizujeme hodnotu dist[i][j] tak jako dist[i][k] + dist[k][j], -li dist[i][j]> dist[i][k] + dist[k][j]
Pseudokód algoritmu Floyda Warshalla:>
Pro k = 0 až n – 1
Pro i = 0 až n – 1
Pro j = 0 až n – 1
Vzdálenost[i, j] = min(Vzdálenost[i, j], Vzdálenost[i, k] + Vzdálenost[k, j])kde i = zdrojový uzel, j = cílový uzel, k = mezilehlý uzel
Ilustrace Floyd Warshall Algorithm:
Doporučený postup Vyzkoušejte!Předpokládejme, že máme graf, jak je znázorněno na obrázku:
Krok 1 : Inicializujte matici Vzdálenost[][] pomocí vstupního grafu tak, že Vzdálenost[i][j]= váha hrany od i na j , také Vzdálenost[i][j] = Nekonečno, pokud není žádná hrana z i na j.
Krok 2 : Ošetřit uzel A jako mezilehlý uzel a vypočítat Vzdálenost[][] pro každý pár uzlů {i,j} pomocí vzorce:
odstranění z binárního vyhledávacího stromu= Vzdálenost[i][j] = minimální (Vzdálenost[i][j], (Vzdálenost od i do A ) + (Vzdálenost od A do j))
= Vzdálenost[i][j] = minimum (Vzdálenost[i][j], Vzdálenost[i][ A ] + Vzdálenost[ A ][j])Krok 3 : Ošetřit uzel B jako mezilehlý uzel a vypočítat Vzdálenost[][] pro každý pár uzlů {i,j} pomocí vzorce:
= Vzdálenost[i][j] = minimální (Vzdálenost[i][j], (Vzdálenost od i do B ) + (Vzdálenost od B do j))
= Vzdálenost[i][j] = minimum (Vzdálenost[i][j], Vzdálenost[i][ B ] + Vzdálenost[ B ][j])číslo 1 milionKrok 4 : Ošetřit uzel C jako mezilehlý uzel a vypočítat Vzdálenost[][] pro každý pár uzlů {i,j} pomocí vzorce:
= Vzdálenost[i][j] = minimální (Vzdálenost[i][j], (Vzdálenost od i do C ) + (Vzdálenost od C do j))
= Vzdálenost[i][j] = minimum (Vzdálenost[i][j], Vzdálenost[i][ C ] + Vzdálenost[ C ][j])Krok 5 : Ošetřit uzel D jako mezilehlý uzel a vypočítat Vzdálenost[][] pro každý pár uzlů {i,j} pomocí vzorce:
= Vzdálenost[i][j] = minimální (Vzdálenost[i][j], (Vzdálenost od i do D ) + (Vzdálenost od D do j))
= Vzdálenost[i][j] = minimum (Vzdálenost[i][j], Vzdálenost[i][ D ] + Vzdálenost[ D ][j])Krok 6 : Ošetřit uzel A jako mezilehlý uzel a vypočítat Vzdálenost[][] pro každý pár uzlů {i,j} pomocí vzorce:
řetězec k itn= Vzdálenost[i][j] = minimální (Vzdálenost[i][j], (Vzdálenost od i do A ) + (Vzdálenost od A do j))
= Vzdálenost[i][j] = minimum (Vzdálenost[i][j], Vzdálenost[i][ A ] + Vzdálenost[ A ][j])Krok 7 : Protože všechny uzly byly považovány za přechodný uzel, můžeme nyní vrátit aktualizovanou matici Vzdálenost[][] jako naši matici odpovědí.
Níže je uvedena implementace výše uvedeného přístupu:
C++ // C++ Program for Floyd Warshall Algorithm #include using namespace std; // Number of vertices in the graph #define V 4 /* Define Infinite as a large enough value.This value will be used for vertices not connected to each other */ #define INF 99999 // A function to print the solution matrix void printSolution(int dist[][V]); // Solves the all-pairs shortest path // problem using Floyd Warshall algorithm void floydWarshall(int dist[][V]) { int i, j, k; /* Add all vertices one by one to the set of intermediate vertices. --->Před začátkem iterace máme nejkratší vzdálenosti mezi všemi páry vrcholů tak, že nejkratší vzdálenosti považují za mezilehlé vrcholy pouze vrcholy v množině {0, 1, 2, .. k-1}. ----> Po skončení iterace se vertex no. k se přidá k množině mezilehlých vrcholů a množina se stane {0, 1, 2, .. k} */ pro (k = 0; k< V; k++) { // Pick all vertices as source one by one for (i = 0; i < V; i++) { // Pick all vertices as destination for the // above picked source for (j = 0; j < V; j++) { // If vertex k is on the shortest path from // i to j, then update the value of // dist[i][j] if (dist[i][j]>(dist[i][k] + dist[k][j]) && (dist[k][j] != INF && dist[i][k] != INF)) dist[i][j] = dist[i][k] + dist[k][j]; } } } // Tisk matice s nejkratší vzdáleností printSolution(dist); } /* Obslužná funkce pro tisk řešení */ void printSolution(int dist[][V]) { cout<< 'The following matrix shows the shortest ' 'distances' ' between every pair of vertices
'; for (int i = 0; i < V; i++) { for (int j = 0; j < V; j++) { if (dist[i][j] == INF) cout << 'INF' << ' '; else cout << dist[i][j] << ' '; } cout << endl; } } // Driver's code int main() { /* Let us create the following weighted graph 10 (0)------->(3) | /| 5 | | | | 1 |/ | (1)------->(2) 3 */ int graf[V][V] = { { 0, 5, INF, 10 }, { INF, 0, 3, INF }, { INF, INF, 0, 1 }, { INF, INF, INF, 0 } }; // Volání funkce floydWarshall(graph); návrat 0; } // Tento kód přispěl Mythri J L> C // C Program for Floyd Warshall Algorithm #include // Number of vertices in the graph #define V 4 /* Define Infinite as a large enough value. This value will be used for vertices not connected to each other */ #define INF 99999 // A function to print the solution matrix void printSolution(int dist[][V]); // Solves the all-pairs shortest path // problem using Floyd Warshall algorithm void floydWarshall(int dist[][V]) { int i, j, k; /* Add all vertices one by one to the set of intermediate vertices. --->Před začátkem iterace máme nejkratší vzdálenosti mezi všemi páry vrcholů tak, že nejkratší vzdálenosti považují za mezilehlé vrcholy pouze vrcholy v množině {0, 1, 2, .. k-1}. ----> Po skončení iterace se vertex no. k se přidá k množině mezilehlých vrcholů a množina se stane {0, 1, 2, .. k} */ pro (k = 0; k< V; k++) { // Pick all vertices as source one by one for (i = 0; i < V; i++) { // Pick all vertices as destination for the // above picked source for (j = 0; j < V; j++) { // If vertex k is on the shortest path from // i to j, then update the value of // dist[i][j] if (dist[i][k] + dist[k][j] < dist[i][j]) dist[i][j] = dist[i][k] + dist[k][j]; } } } // Print the shortest distance matrix printSolution(dist); } /* A utility function to print solution */ void printSolution(int dist[][V]) { printf( 'The following matrix shows the shortest distances' ' between every pair of vertices
'); for (int i = 0; i < V; i++) { for (int j = 0; j < V; j++) { if (dist[i][j] == INF) printf('%7s', 'INF'); else printf('%7d', dist[i][j]); } printf('
'); } } // driver's code int main() { /* Let us create the following weighted graph 10 (0)------->(3) | /| 5 | | | | 1 |/ | (1)------->(2) 3 */ int graf[V][V] = { { 0, 5, INF, 10 }, { INF, 0, 3, INF }, { INF, INF, 0, 1 }, { INF, INF, INF, 0 } }; // Volání funkce floydWarshall(graph); návrat 0; }> Jáva // Java program for Floyd Warshall All Pairs Shortest // Path algorithm. import java.io.*; import java.lang.*; import java.util.*; class AllPairShortestPath { final static int INF = 99999, V = 4; void floydWarshall(int dist[][]) { int i, j, k; /* Add all vertices one by one to the set of intermediate vertices. --->Před začátkem iterace máme nejkratší vzdálenosti mezi všemi páry vrcholů tak, že nejkratší vzdálenosti považují za mezilehlé vrcholy pouze vrcholy v množině {0, 1, 2, .. k-1}. ----> Po skončení iterace se vertex no. k se přidá k množině mezilehlých vrcholů a množina se stane {0, 1, 2, .. k} */ pro (k = 0; k< V; k++) { // Pick all vertices as source one by one for (i = 0; i < V; i++) { // Pick all vertices as destination for the // above picked source for (j = 0; j < V; j++) { // If vertex k is on the shortest path // from i to j, then update the value of // dist[i][j] if (dist[i][k] + dist[k][j] < dist[i][j]) dist[i][j] = dist[i][k] + dist[k][j]; } } } // Print the shortest distance matrix printSolution(dist); } void printSolution(int dist[][]) { System.out.println( 'The following matrix shows the shortest ' + 'distances between every pair of vertices'); for (int i = 0; i < V; ++i) { for (int j = 0; j < V; ++j) { if (dist[i][j] == INF) System.out.print('INF '); else System.out.print(dist[i][j] + ' '); } System.out.println(); } } // Driver's code public static void main(String[] args) { /* Let us create the following weighted graph 10 (0)------->(3) | /| 5 | | | | 1 |/ | (1)------->(2) 3 */ int graf[][] = { { 0, 5, INF, 10 }, { INF, 0, 3, INF }, { INF, INF, 0, 1 }, { INF, INF, INF, 0 } }; AllPairShortestPath a = new AllPairShortestPath(); // Volání funkce a.floydWarshall(graph); } } // Přispěl Aakash Hasija> Python3 # Python3 Program for Floyd Warshall Algorithm # Number of vertices in the graph V = 4 # Define infinity as the large # enough value. This value will be # used for vertices not connected to each other INF = 99999 # Solves all pair shortest path # via Floyd Warshall Algorithm def floydWarshall(graph): ''' dist[][] will be the output matrix that will finally have the shortest distances between every pair of vertices ''' ''' initializing the solution matrix same as input graph matrix OR we can say that the initial values of shortest distances are based on shortest paths considering no intermediate vertices ''' dist = list(map(lambda i: list(map(lambda j: j, i)), graph)) ''' Add all vertices one by one to the set of intermediate vertices. --->Před začátkem iterace máme nejkratší vzdálenosti mezi všemi dvojicemi vrcholů tak, že nejkratší vzdálenosti považují za mezilehlé vrcholy pouze vrcholy v množině {0, 1, 2, .. k-1}. ----> Po skončení iterace se vertex no. k se přidá k množině mezilehlých vrcholů a množina se stane {0, 1, 2, .. k} ''' pro k v rozsahu (V): # vybrat všechny vrcholy jako zdroj jeden po druhém pro i v range(V): # Vyberte všechny vrcholy jako cíl pro # výše vybraný zdroj pro j v rozsahu(V): # Pokud je vrchol k na nejkratší cestě z # i do j, aktualizujte hodnotu dist[i][ j] dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j] ) printSolution(dist) # Obslužná funkce pro tisk řešení def printSolution (dist): print('Následující matice ukazuje nejkratší vzdálenosti mezi každou dvojicí vrcholů') pro i v rozsahu(V): pro j v rozsahu(V): if(dist[i][j] == INF): print('%7s' % ('INF'), end=' ') else: print('%7d ' % (dist[i][j]), end=' ') if j == V-1: print() # Kód řidiče if __name__ == '__main__': ''' 10 (0)------ ->(3) | /| 5 | | | | 1 |/ | (1)------->(2) 3 ''' graf = [[0, 5, INF, 10], [INF, 0, 3, INF], [INF, INF, 0 , 1], [INF, INF, INF, 0] ] # Volání funkce floydWarshall(graph) # Tento kód přispěl Mythri J L> C# // C# program for Floyd Warshall All // Pairs Shortest Path algorithm. using System; public class AllPairShortestPath { readonly static int INF = 99999, V = 4; void floydWarshall(int[, ] graph) { int[, ] dist = new int[V, V]; int i, j, k; // Initialize the solution matrix // same as input graph matrix // Or we can say the initial // values of shortest distances // are based on shortest paths // considering no intermediate // vertex for (i = 0; i < V; i++) { for (j = 0; j < V; j++) { dist[i, j] = graph[i, j]; } } /* Add all vertices one by one to the set of intermediate vertices. --->Před začátkem iterace máme nejkratší vzdálenosti mezi všemi dvojicemi vrcholů tak, že nejkratší vzdálenosti považují za mezilehlé vrcholy pouze vrcholy v množině {0, 1, 2, .. k-1}. ---> Po skončení iterace se vertex no. k se přidá k množině mezilehlých vrcholů a množina se stane {0, 1, 2, .. k} */ pro (k = 0; k< V; k++) { // Pick all vertices as source // one by one for (i = 0; i < V; i++) { // Pick all vertices as destination // for the above picked source for (j = 0; j < V; j++) { // If vertex k is on the shortest // path from i to j, then update // the value of dist[i][j] if (dist[i, k] + dist[k, j] < dist[i, j]) { dist[i, j] = dist[i, k] + dist[k, j]; } } } } // Print the shortest distance matrix printSolution(dist); } void printSolution(int[, ] dist) { Console.WriteLine( 'Following matrix shows the shortest ' + 'distances between every pair of vertices'); for (int i = 0; i < V; ++i) { for (int j = 0; j < V; ++j) { if (dist[i, j] == INF) { Console.Write('INF '); } else { Console.Write(dist[i, j] + ' '); } } Console.WriteLine(); } } // Driver's Code public static void Main(string[] args) { /* Let us create the following weighted graph 10 (0)------->(3) | /| 5 | | | | 1 |/ | (1)------->(2) 3 */ int[, ] graf = { { 0, 5, INF, 10 }, { INF, 0, 3, INF }, { INF, INF, 0 , 1 }, { INF, INF, INF, 0 } }; AllPairShortestPath a = new AllPairShortestPath(); // Volání funkce a.floydWarshall(graph); } } // Autorem tohoto článku je // Abdul Mateen Mohammed> Javascript // A JavaScript program for Floyd Warshall All // Pairs Shortest Path algorithm. var INF = 99999; class AllPairShortestPath { constructor() { this.V = 4; } floydWarshall(graph) { var dist = Array.from(Array(this.V), () =>new Array(this.V).fill(0)); var i, j, k; // Inicializujeme matici řešení // stejně jako vstupní grafovou matici // Nebo můžeme říci, že počáteční // hodnoty nejkratších vzdáleností // jsou založeny na nejkratších cestách // bez ohledu na mezilehlý // vrchol pro (i = 0; i< this.V; i++) { for (j = 0; j < this.V; j++) { dist[i][j] = graph[i][j]; } } /* Add all vertices one by one to the set of intermediate vertices. --->Před začátkem iterace máme nejkratší vzdálenosti mezi všemi dvojicemi vrcholů tak, že nejkratší vzdálenosti považují za mezilehlé vrcholy pouze vrcholy v množině {0, 1, 2, .. k-1}. ---> Po skončení iterace se vertex no. k se přidá k množině mezilehlých vrcholů a množina se stane {0, 1, 2, .. k} */ pro (k = 0; k< this.V; k++) { // Pick all vertices as source // one by one for (i = 0; i < this.V; i++) { // Pick all vertices as destination // for the above picked source for (j = 0; j < this.V; j++) { // If vertex k is on the shortest // path from i to j, then update // the value of dist[i][j] if (dist[i][k] + dist[k][j] < dist[i][j]) { dist[i][j] = dist[i][k] + dist[k][j]; } } } } // Print the shortest distance matrix this.printSolution(dist); } printSolution(dist) { document.write( 'Following matrix shows the shortest ' + 'distances between every pair of vertices ' ); for (var i = 0; i < this.V; ++i) { for (var j = 0; j < this.V; ++j) { if (dist[i][j] == INF) { document.write(' INF '); } else { document.write(' ' + dist[i][j] + ' '); } } document.write(' '); } } } // Driver Code /* Let us create the following weighted graph 10 (0)------->(3) | /| 5 | | | | 1 |/ | (1)------->(2) 3 */ var graf = [ [0, 5, INF, 10], [INF, 0, 3, INF], [INF, INF, 0, 1] , [INF, INF, INF, 0], ]; var a = new AllPairShortestPath(); // Vytiskne řešení a.floydWarshall(graph); // Tento kód přispěl rdtaank.> PHP // PHP Program for Floyd Warshall Algorithm // Solves the all-pairs shortest path problem // using Floyd Warshall algorithm function floydWarshall ($graph, $V, $INF) { /* dist[][] will be the output matrix that will finally have the shortest distances between every pair of vertices */ $dist = array(array(0,0,0,0), array(0,0,0,0), array(0,0,0,0), array(0,0,0,0)); /* Initialize the solution matrix same as input graph matrix. Or we can say the initial values of shortest distances are based on shortest paths considering no intermediate vertex. */ for ($i = 0; $i < $V; $i++) for ($j = 0; $j < $V; $j++) $dist[$i][$j] = $graph[$i][$j]; /* Add all vertices one by one to the set of intermediate vertices. --->Před začátkem iterace máme nejkratší vzdálenosti mezi všemi páry vrcholů tak, že nejkratší vzdálenosti považují za mezilehlé vrcholy pouze vrcholy v množině {0, 1, 2, .. k-1}. ----> Po skončení iterace se vertex no. k se přidá k množině mezilehlých vrcholů a množina se stane {0, 1, 2, .. k} */ for ($k = 0; $k< $V; $k++) { // Pick all vertices as source one by one for ($i = 0; $i < $V; $i++) { // Pick all vertices as destination // for the above picked source for ($j = 0; $j < $V; $j++) { // If vertex k is on the shortest path from // i to j, then update the value of dist[i][j] if ($dist[$i][$k] + $dist[$k][$j] < $dist[$i][$j]) $dist[$i][$j] = $dist[$i][$k] + $dist[$k][$j]; } } } // Print the shortest distance matrix printSolution($dist, $V, $INF); } /* A utility function to print solution */ function printSolution($dist, $V, $INF) { echo 'The following matrix shows the ' . 'shortest distances between ' . 'every pair of vertices
'; for ($i = 0; $i < $V; $i++) { for ($j = 0; $j < $V; $j++) { if ($dist[$i][$j] == $INF) echo 'INF ' ; else echo $dist[$i][$j], ' '; } echo '
'; } } // Drivers' Code // Number of vertices in the graph $V = 4 ; /* Define Infinite as a large enough value. This value will be used for vertices not connected to each other */ $INF = 99999 ; /* Let us create the following weighted graph 10 (0)------->(3) | /| 5 | | | | 1 |/ | (1)------->(2) 3 */ $graf = pole(pole(0, 5, $INF, 10), pole($INF, 0, 3, $INF), pole($ INF, $INF, 0, 1), pole($INF, $INF, $INF, 0)); // Volání funkce floydWarshall($graph, $V, $INF); // Tento kód přispěl Ryuga ?>> Výstup
The following matrix shows the shortest distances between every pair of vertices 0 5 8 9 INF 0 3 4 INF INF 0 1 INF INF INF 0>
Analýza složitosti algoritmu Floyd Warshall:
- Časová náročnost: O(V3), kde V je počet vrcholů v grafu a spustíme tři vnořené smyčky, každou o velikosti V
- Pomocný prostor: O(V2), k vytvoření 2-D matice za účelem uložení nejkratší vzdálenosti pro každý pár uzlů.
Poznámka : Výše uvedený program tiskne pouze nejkratší vzdálenosti. Řešení můžeme upravit pro tisk nejkratších cest také uložením informací o předchůdci do samostatné 2D matice.
Proč je Floyd-Warshall Algorithm lepší pro husté grafy a ne pro řídké grafy?
Hustý graf : Graf, ve kterém je počet hran výrazně vyšší než počet vrcholů.
Řídký graf : Graf, ve kterém je počet hran velmi nízký.Bez ohledu na to, kolik hran je v grafu Algoritmus Floyda Warshalla běží na O(V3) časy, proto se nejlépe hodí pro Husté grafy . V případě řídkých grafů Johnsonův algoritmus je vhodnější.
Důležité otázky k rozhovoru týkající se Floyd-Warshall:
- Jak detekovat negativní cyklus v grafu pomocí Floyd Warshall Algorithm?
- Jak se Floyd-warshallův algoritmus liší od Dijkstrova algoritmu?
- Jak se Floyd-warshallův algoritmus liší od Bellman-Fordova algoritmu?
Skutečné aplikace Floyd-Warshallova algoritmu:
- V počítačových sítích lze tento algoritmus použít k nalezení nejkratší cesty mezi všemi páry uzlů v síti. Toto se nazývá jako směrování sítě .
- Konektivita letu V leteckém průmyslu najít nejkratší cestu mezi letišti.
- GIS ( Geografické informační systémy ) aplikace často zahrnují analýzu prostorových dat, jako jsou silniční sítě, za účelem nalezení nejkratších cest mezi místy.
- Kleeneův algoritmus což je zobecnění floyd warshall, lze použít k nalezení regulárního výrazu pro regulární jazyk.






