Pathfinding: A* Vyhledávací Algoritmus

krok nahoru od dijkstrův algoritmus je* (přečtěte si: „hvězda“). Pokud jde o hledání cest, dijkstrův algoritmus bude chtít vyzkoušet každou cestu a každý vrchol najít nejkratší cestu mezi výchozím bodem a destinací, vzhledem K tomu, že* má navíc atribut, heuristika, která by měla umožnit najít nejkratší cestu, aniž byste museli kontrolovat každou cestu a vrchol. Každý algoritmus má své případy použití, ale obecně lze říci, že jak Dijkstra, tak a* mohou najít nejkratší cestu, ale a* to udělá rychleji.

doporučil bych vědět něco o dijkstrův algoritmus, než jít do tohoto článku, protože existuje mnoho bodů, pro srovnání. Nebo ještě lépe, přečtěte si můj poslední článek na toto téma! https://medium.com/swlh/pathfinding-dijkstras-algorithm-65e71c346629

budu muset nastavit několik věcí pro své příklady, plus dát definici toho, co je heuristická. Nejprve vám ukážu typ grafu, který chci použít pro své příklady.

Sotva grafu. Spíš šachovnice.

Toto je trochu abstraktní, ale chci použít kostkovanou desku jako svůj graf a chci povolit pohyb mezi jejími čtverci. Pokud překrývám ekvivalentní graf s vrcholy a hranami, mělo by to vypadat nějak takto.

to je taky linek. Možná ne tak užitečné …

Vezměme si například středový čtverec/vrchol, E. Má osm sousedních vrcholů, takže se můžeme pohybovat nahoru, dolů, doleva, doprava a ve všech diagonálních kombinacích každého z nich. A to je opravdu vše, co jsem se zde snažil nastavit: budu používat šachovnici a povolím pohyb v osmi směrech. Trochu rozvláčný, ale teď se začneme dívat na pohyb a náklady na pohyb.

Začínáme jednoduše, řeknu, že pohyb nahoru, dolů, doleva a doprava má náklady na pohyb 1. Deska je stále zaneprázdněn, takže budu extrahovat graf, a přidat, že pohyb náklady na jako hrana závaží.

Protože jsme pathfinding, můžeme myslet, že tyto váhy jako je vzdálenost.

pokud jsou tyto váhy vzdálenosti a pokud jsou vztahy a sousedé rozloženy takto, pak nám geometrie může říci o nákladech na diagonální pohyby. Pomocí Pythagorova Theora bychom měli dostat √(12 + 12) = √2, což je zhruba 1.41421356237 … což není moc pěkné číslo na práci. Takže ukradnu nápad (a cituji své zdroje!), a násobit a zaokrouhlit náklady dolů. Pro oba typy pohybu je vynásobím deseti a potom jejich desetinná místa zkrátím. To nám poskytne konečné náklady 10 pro pohyby nahoru, dolů, doleva a doprava a 14 pro diagonální pohyby.

Pěkné kulaté číslo pro všechno. To také znamená, že dělat diagonální pohyby jsou levnější, než dělat dva non-diagonální pohyb na stejném náměstí (10 + 10 >14)

Heuristiky

mám pocit, že tyhle jsou pro mě těžké definovat, takže začnu s Wikipedie je otevření linky na téma:

V computer science, umělé inteligence a matematické optimalizace, heuristické (z řeckého εὑρίσκω „najít, objevit“) je technika určená pro řešení problému více rychle, když klasické metody jsou příliš pomalé, nebo pro nalezení přibližného řešení, když klasické metody nedokáží najít žádné přesné řešení. Toho je dosaženo optimálností obchodování, úplností, přesností nebo přesností rychlosti. Svým způsobem to lze považovat za zkratku.

je to užitečné? Chápeš to? Protože to nechápu. Myslím, trochu to chápu, a je to přesný popis, ale pokud to bylo první, co jste kdy slyšeli o heuristice, Nejsem si jistý, že byste získali úplný obrázek o tom, co je heuristika z tohoto. Možná, že když vám řeknu o heuristickém hledání cesty, budete mít lepší přehled.

u dijkstrova algoritmu byl důraz kladen na jednu hodnotu: nejkratší vzdálenost od počátečního indexu. Což, když se nad tím zamyslíte, je trochu zvláštní. Tento algoritmus se snaží najít nové, kratší cesty k nějakému cíli, ale vždy se zaměřuje na to, kde začal. Představte si, že někdo chodí na potraviny, ale celou cestu chodí dozadu, snaží se dávat pozor na svůj domov, dokud se nedostanou do obchodu. V reálném životě by to pravděpodobně nefungovalo, ale možná, kdybyste jim dali čas jít po celém městě, mohlo by to nakonec fungovat.

Pokud jde o tuto praštěnou analogii, a* se liší od Dijkstra, protože naznačuje, že se otočí a jde vpřed. A*, stejně jako Dijkstra, také sleduje, jak daleko od domova je, ale jeho jedinečnou vlastností je, že také sleduje, jak daleko je od cíle. Při dalším kroku se Dijkstra podívá na to, která cesta je v současné době nejkratší, ale a * jde o krok dále a také zvažuje, zda tento krok posune blíže k cíli. Zjednodušeně řečeno, A* má hrubý odhad zbývající vzdálenosti od svého cíle, a když se tento odhad přiblíží nule, ví, že se pohybuje správným směrem. Toto je heuristika, kterou použijeme v našich příkladech.

krokování algoritmem

to bude poměrně jednoduchý příklad, ale měl by vám ukázat základní tok a opakování algoritmu. Budu ujistěte se, že poskytovat odkazy v mé odkazy na jiné, složitější příklady, ale to by mělo být dobrý základ pro ty. Budu používat set-up podobný, jak jsem ukázal dijkstrův.

Pojďme se nad těmito komponenty. Nejprve máme desku 4×3, která bude naším grafem. Naším cílem bude najít nejkratší cestu mezi A A L. jakmile začnu ukazovat kroky, odstraním písmena, ale tady jsou prozatím jejich štítky. Pod deskou jsou dvě sady používané ke sledování vrcholů. Na rozdíl od dijkstry Neuchováváme každý vrchol ve startovní sadě (jako „Unvisited“), ale přidáme je k otevření, jakmile jsou objeveny jako sousedé s aktuálním vrcholem. Konečně stůl. Hodně jako Dijkstra, ale s dalšími dvěma sloupci pro heuristickou vzdálenost a součtem dvou vzdáleností.

další rozdíl mezi Dijkstra a* je, že dijkstrův dostane na začátek smyčky okamžitě, ale* má udělat malý set-up pro její počáteční vrchol. Udělejme to nyní a získejme trochu představu o tom, jak bude tabulka fungovat.

za Prvé, přidáme na Otevřený soubor. Za druhé, zjistíme vzdálenost A od začátku. Přirozeně, vzdálenost od A do a je nula, takže to bude přidáno do tabulky, a to bude číslo v levém horním rohu čtverce A. Za třetí určíme heuristickou vzdálenost. Můžeme to udělat libovolným počtem způsobů, vše, co je důležité, je, že změříme tuto vzdálenost stejným způsobem pro každý čtverec. Budu používat vzdálenost „jak vrána letí“ pro všechny heuristické vzdálenosti, což znamená, že mohu znovu použít Pythagorovu větu. V tomto případě, budeme výpočtu √(202 + 302), a zjistíte, že je vzdálenost 36.0555127546… od L (budu kolo desetinná místa na nejbližší desetinu pro úsporu místa). Přidám to ke stolu a umístím to do pravého horního rohu čtverce A. Nakonec suma. Přidám nejkratší vzdálenost od začátku k heuristické vzdálenosti, přidám ji do tabulky a umístím ji do středu čtverce A.

to je náš výchozí bod, a nyní se můžeme podívat na sousedy A a přidat jejich hodnoty do tabulky.

za Prvé, přidáme B, E, a F Otevřete nastavení. Další, můžeme najít jejich nejkratší vzdálenosti od začátku, a protože všechno je jeden krok od začátku, to bude jen 10 je pro B a E, a 14 pro diagonální přesun do F. Pro heuristické vzdálenost, použijeme Pythagorovu Větu z každého náměstí na konec vrchol. Nakonec dostaneme jejich částky a přidáme „A“ ke každému z jejich předchozích vrcholů.

v tomto okamžiku jsme udělali vše, co potřebujeme S A, takže se přesune do uzavřené sady a budeme potřebovat nový aktuální vrchol. Chcete-li zjistit, který vrchol by měl být zkoumán dále, podíváme se na otevřenou sadu a najdeme vrchol, který má nejnižší součet. Právě teď je to F se součtem 36,1. Takže z něj uděláme aktuální vrchol a začneme pracovat na hodnotách pro své sousedy.

F má osm sousedů, ale jen pět se změní. Za prvé, A je nyní v uzavřené sadě, takže ji nyní nelze změnit. Pro zbývajících sedm je přidáme do otevřené sady (pokud již nejsou součástí) a pak pojďme pracovat na jejich vzdálenostech od začátku. To bude fungovat hodně podobně jako Dijikstra algoritmus, a budeme přidávat F je vzdálenost od počátku, aby každý z jeho sousedů je vzdálenost od F. Na našem stole, F je vzdálenost od počátku je 14, takže budeme vyplňování 14+10=24 nebo 14+14=28 pro tyto. B A E však již mají kratší vzdálenosti od začátku, takže jejich tabulky se neaktualizují. To ponechává pět vrcholů, které budou aktualizovány, s C, já, a k získání 28, A G A J získání 24 pro jejich vzdálenost od začátku. Dále použijte Pythagorovu větu pro heuristické vzdálenosti každého z těchto vrcholů, poté Vypočítejte jejich součty a nakonec přidejte „F“ do předchozího sloupce vrcholu pro vrcholy, které byly aktualizovány.

F je kompletní a budou přesunuty do Uzavřené nastavit, a nový aktuální vrchol bude vybrán na základě které vrchol v Otevřeném nastavení má nejnižší součet. Je to velmi blízko, ale K je jednu desetinu menší (A ano, je to z důvodu zaokrouhlení rozdíl, ale v tomto případě, to se ukázalo být dobrým tie breaker). K bude nový vrchol zkoumat, takže začněme tím, že se podíváme na jeho sousedy.

K má šest sousedů, tři z nich jsou již v Otevřené nastavit, takže poslední dva H a L budou přidány do Otevřené nastavit stejně. Nyní vypočítáme jejich vzdálenosti od začátku. Vzdálenost K od začátku je 28,takže budeme pracovat s 28 + 10=38 Pro G, J A L a 28 + 14=42 pro H. G A J však již mají menší vzdálenosti, takže nebudou aktualizovány. Najdeme heuristické vzdálenosti, vypočítat jejich sumy, a přidat „K“ na předchozí vrchol, který byl aktualizován.

K je kompletní a přesunut do uzavřené sady a další vrchol v otevřeném prostoru s nejmenším součtem je L, náš cíl!

Nyní, že L je aktuální vrchol, algoritmus končí, a můžeme použít naši tabulku sledovat cestu zpět na začátek:

  • L je předchozí vrchol je K
  • K předchozí vrchol je F
  • F‘ předchozí vrchol je počáteční vrchol.

Tak, to znamená, že nejkratší cesta je > F > K > L

analýza výsledků

ve srovnání s dijkstrovým algoritmem za sebou A* zanechala docela nepořádek. Podívejme se na několik lichých bodů. Začněte, podívejte se na vrchol C a jeho vzdálenost od začátku: 28. To se zdá divné, protože A A C jsou jen dva vodorovné pohyby od sebe, takže nejkratší vzdálenost by měla být 20. Teď, C si myslí, že jeho nejkratší cestu k jsou dvě diagonální pohyby prostřednictvím F.

Když dijkstrův algoritmus končí, je třeba poskytnout velmi kompletní tabulku vzdáleností od výchozího bodu. Naopak, tabulka A*má nesprávné hodnoty a zcela chybí vertex D. ale dostala stejnou odpověď, jakou by měla Dijkstra, a udělala mnohem rychleji. Dijkstra ‚ s by se chtěl podívat na všech 12 vrcholů, než prohlásí, že našel nejkratší cestu; a * se musel podívat pouze na 4, než našel správnou cestu. Tato změna v rychlosti je vzhledem k heuristické jsme byli použití: tak často, jak jsme mohli, chtěli jsme být zavření vzdálenost našeho cíle. Pokud se vrátíme k definici heuristiky na Wikipedii, a * vyměnila úplnost za rychlost.

zkusme další malý příklad, ale s překážkou na cestě k cíli.

Výchozí bod je levý horní vrchol a* se snaží najít nejkratší cestu k pravé dolní vrchol. Černé čtverce představují mezeru v grafu a nelze je procházet. Pokud A* sleduje svou heuristiku „vždy se přibližte k cíli“, tyto černé čtverečky ji povedou do slepé uličky.

V tomto bodě,* bude vypadat pro nejmenší částky, které budou čtverce těsně pod a vpravo od výchozího vrcholu. A * prozkoumá obě cesty, ale sestupná cesta se dostane do další slepé uličky a doprava najde cestu kolem černých čtverců. Mohlo by to hrát trochu jinak než toto, ale předpokládejme, že takto* zpracoval tento scénář. I když se dostal do slepých uliček, byl schopen se vrátit a najít jinou cestu, a nemusel se dívat na každý vrchol (úplně pravý horní vrchol byl znovu přeskočen). To znamená, že když hvězda * běží v absolutním nejhorším stavu, je v podstatě stejně rychlá jako normální výkon Dijkstry. Každý algoritmus má dokonale platné případy použití, ale pokud jde o hledání cesty a nalezení nejkratších cest, a* je lepší volbou.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.