Floyd-Warshall algoritmus | |
---|---|
Pojmenoval podle | Robert Floyd a Stephen Warshall |
Autor | Bernard Roy [d] |
účel | hledat v grafu nejkratší cesty mezi libovolným párem vrcholů |
Datová struktura | graf |
nejhorší čas | |
Nejlepší čas | |
Průměrný čas | |
Náklady na paměť | |
Mediální soubory na Wikimedia Commons |
V informatice je Floyd-Warshallův algoritmus (také známý jako Floydův algoritmus , Roy-Warshallův algoritmus , Roy-Floydův algoritmus nebo WFI algoritmus ) algoritmem pro hledání nejkratších cest ve váženém grafu (ale s kladnou nebo zápornou váhou hran) . žádné negativní cykly). V jednom provedení algoritmu budou nalezeny délky (celkové váhy) nejkratších cest mezi všemi dvojicemi vrcholů. Přestože nevrací podrobnosti o samotných cestách, je možné cesty rekonstruovat jednoduchými úpravami algoritmu. K nalezení tranzitivního uzavření vztahu lze také použít varianty algoritmunebo (ve spojení se Schulzeho hlasovacím systémem ) nejširší cesty mezi všemi dvojicemi vrcholů ve váženém grafu.
Algoritmus Floyd-Warshall je příkladem dynamického programování a byl publikován ve své nyní akceptované podobě Robertem Floydem v roce 1962. Je však v podstatě stejný jako algoritmy dříve publikované Bernardem Royem v roce 1959 a také Stephenem Warshallem v roce 1962 pro nalezení tranzitivního uzavření grafu a úzce souvisí s Kleeneovým algoritmem (publikovaným v roce 1956) pro převod deterministického konečného automat na regulární výraz . Moderní formulaci algoritmu ve formě tří vnořených smyček for poprvé popsal Peter Ingerman také v roce 1962.
Uvažujme graf s vrcholy očíslovanými od 1 do . Algoritmus Floyd-Warshall porovnává všechny možné cesty grafem mezi každou dvojicí vrcholů. Může to udělat pro srovnání v grafu, i když graf může mít až hran a každá kombinace hran je kontrolována. Toho je dosaženo postupným zlepšováním odhadu nejkratší cesty mezi dvěma vrcholy, dokud není odhad optimální.
Dále zvažte funkci , která vrací nejkratší možnou cestu z do pomocí pouze vrcholů z množiny jako mezilehlých bodů podél této cesty. Nyní, vzhledem k této funkci, je naším cílem najít nejkratší cestu z každého do každého pomocí libovolného vrcholu v .
Pro každou z těchto dvojic vrcholů může být buď
(1) cesta, která neprochází (používá pouze vrcholy z množiny ),nebo
(2) cesta, která prochází (od do a poté z do , v obou případech se používají pouze mezilehlé vrcholy v ).Víme, že nejlepší cesta z do , což je cesta, která používá pouze vrcholy c do , je definována jako , a je jasné, že pokud by existovala lepší cesta z do do , pak by délka této cesty byla řetězcem tvořeným nejkratší cesty z do (pouze pomocí mezilehlých vrcholů v ) a nejkratší cesty z do (pouze pomocí mezilehlých vrcholů v ).
Jestliže je váha hrany mezi vrcholy a , můžeme ji definovat pomocí následujícího rekurzivního vzorce:
základní případ
a rekurzivní případ
.Tento vzorec tvoří základ Floyd-Warshallova algoritmu. Algoritmus funguje tak, že nejprve počítá pro všechny páry pro , a pak , a tak dále. Tento proces pokračuje, dokud není nalezena nejkratší cesta pro všechny páry pomocí jakýchkoli mezilehlých vrcholů. Pseudokód pro tuto základní verzi je následující:
nechť je dist |V| × |V| pole minimálních vzdáleností inicializovaných jako ∞ (nekonečno) pro každou hranu ( u , v ) do dist[ u ][ v ] ← w( u , v ) // Váha hrany ( u , v ) pro každý vrchol v do dist[ v ][ v ] ← 0 pro k od 1 do |V| pro i od 1 do |V| pro j od 1 do |V| if dist[ i ][ j ] > dist[ i ][ k ] + dist[ k ][ j ] dist[ i ][ j ] ← dist[ i ][ k ] + dist[ k ][ j ] konec ifVýše uvedený algoritmus je proveden na grafu vlevo dole:
Až do první rekurze vnější smyčky, označované výše k = 0, jediné známé cesty odpovídají jednotlivým hranám v grafu. Pro k = 1 jsou nalezeny cesty, které procházejí vrcholem 1: konkrétně je nalezena cesta [2,1,3], která nahradí cestu [2,3], která má méně hran, ale je delší (z hlediska hmotnosti ). Pro k = 2 jsou nalezeny cesty, které procházejí vrcholy 1,2. Červené a modré rámečky ukazují, jak je cesta [4,2,1,3] sestavena ze dvou známých cest [4,2] a [2,1,3], se kterými jsme se setkali v předchozích iteracích, se 2 na průsečíku. Cesta [4,2,3] se nebere v úvahu, protože [2,1,3] je nejkratší cesta, se kterou jsme se dosud setkali od 2 do 3. Pro k = 3 jsou nalezeny cesty procházející vrcholy 1,2,3. Nakonec pro k = 4 jsou nalezeny všechny nejkratší cesty.
Matice vzdáleností v každé iteraci k, aktualizované vzdálenosti tučně , bude:
k = 0 | j | ||||
jeden | 2 | 3 | čtyři | ||
---|---|---|---|---|---|
i | jeden | 0 | ∞ | −2 | ∞ |
2 | čtyři | 0 | 3 | ∞ | |
3 | ∞ | ∞ | 0 | 2 | |
čtyři | ∞ | −1 | ∞ | 0 |
k = 1 | j | ||||
jeden | 2 | 3 | čtyři | ||
---|---|---|---|---|---|
i | jeden | 0 | ∞ | −2 | ∞ |
2 | čtyři | 0 | 2 | ∞ | |
3 | ∞ | ∞ | 0 | 2 | |
čtyři | ∞ | −1 | ∞ | 0 |
k = 2 | j | ||||
jeden | 2 | 3 | čtyři | ||
---|---|---|---|---|---|
i | jeden | 0 | ∞ | −2 | ∞ |
2 | čtyři | 0 | 2 | ∞ | |
3 | ∞ | ∞ | 0 | 2 | |
čtyři | 3 | −1 | jeden | 0 |
k = 3 | j | ||||
jeden | 2 | 3 | čtyři | ||
---|---|---|---|---|---|
i | jeden | 0 | ∞ | −2 | 0 |
2 | čtyři | 0 | 2 | čtyři | |
3 | ∞ | ∞ | 0 | 2 | |
čtyři | 3 | −1 | jeden | 0 |
k = 4 | j | ||||
jeden | 2 | 3 | čtyři | ||
---|---|---|---|---|---|
i | jeden | 0 | −1 | −2 | 0 |
2 | čtyři | 0 | 2 | čtyři | |
3 | 5 | jeden | 0 | 2 | |
čtyři | 3 | −1 | jeden | 0 |
Záporný cyklus je cyklus, jehož součet hran je záporný. Mezi žádnou dvojicí vrcholů , , které jsou součástí záporného cyklu, neexistuje nejkratší cesta, protože délka cesty od do může být libovolně malá (záporná). Pro numericky smysluplný výstup předpokládá Floyd-Warshall algoritmus, že neexistují žádné negativní cykly. Pokud však existují negativní cykly, lze k jejich detekci použít Floyd-Warshall algoritmus. Algoritmus je samozřejmě následující:
mezi všemi páry vrcholů , včetně těch, kde ;
méně než nula, tzn. označuje negativní cyklus;
existuje cesta záporné délky od do .
Pro detekci negativních cyklů pomocí Floyd-Warshallova algoritmu je tedy možné zkontrolovat úhlopříčku matice nejkratší cesty a přítomnost záporného čísla znamená, že graf obsahuje alespoň jeden negativní cyklus. Během provádění algoritmu, pokud dojde k zápornému cyklu, se mohou objevit exponenciálně velká čísla až , kde je největší absolutní hodnota záporné hrany v grafu. Abyste se vyhnuli problémům s přetečením/podtečením, měli byste zkontrolovat záporná čísla na diagonále matice nejkratší cesty uvnitř vnitřní smyčky for algoritmu. Je zřejmé, že v neorientovaném grafu záporná hrana vytváří negativní cyklus (tj. uzavřený okruh) včetně jeho dopadajících vrcholů. Pokud vezmeme v úvahu všechny hrany výše uvedeného příkladu grafu jako neorientované, například posloupnost vrcholů 4 - 2 - 4 je cyklus se součtem vah -2.
Algoritmus Floyd-Warshall obvykle poskytuje pouze délky cest mezi všemi páry vrcholů. Jednoduchými úpravami lze vytvořit metodu pro rekonstrukci skutečné cesty mezi libovolnými dvěma vrcholy koncových bodů. I když někdo může mít sklon uložit 3 skutečné cesty z každého vrcholu do každého druhého vrcholu, není to nutné a ve skutečnosti je to z hlediska paměti velmi drahé. Místo toho lze pro každý uzel v čase vypočítat strom nejkratší cesty pomocí paměti k uložení každého stromu, což nám umožňuje efektivně rekonstruovat cestu z libovolných dvou spojených vrcholů.
Nechť je počet vrcholů. K nalezení všech ( pro všechny a ) z vyžaduje operace. Protože začínáme a počítáme posloupnost matic , , , , celkový počet použitých operací je . Proto je složitost algoritmu .
Algoritmus Floyd-Warshall lze použít k řešení následujících problémů, zejména:
Floyd-Warshallův algoritmus je účinný pro výpočet všech nejkratších cest v hustých grafech , když je mezi páry vrcholů mnoho párů hran. V případě řídkých grafů s hranami nezáporné váhy je nejlepší volbou použít Dijkstrův algoritmus pro každý možný uzel. S touto volbou je složitost při použití binární haldy , která je lepší než algoritmus Floyd-Warshall, když je výrazně menší (podmínka řídkosti grafu). Pokud je graf řídký, má hrany se zápornou váhou a nejsou zde žádné cykly se zápornou celkovou váhou, pak se použije Johnsonův algoritmus , který má stejnou složitost jako varianta s Dijkstrovým algoritmem.
Známé jsou také algoritmy využívající algoritmy rychlého násobení matic , které urychlují výpočty v hustých grafech, ale obvykle mají další omezení (například reprezentovat váhy hran jako malá celá čísla) [2] [3] . Zároveň se díky velkému konstantnímu faktoru doby běhu výpočetní výhoda oproti algoritmu Floyd–Warshall projevuje pouze na velkých grafech.
Algoritmy vyhledávání grafů | ||
---|---|---|
Neinformované metody | ||
Informované metody | ||
Zkratky | ||
Minimální kostra | ||
jiný |