Patrzyłem na to, co robią zawodnicy Mario AI Competition , a niektórzy z nich zbudowali całkiem zgrabne boty Mario, wykorzystując algorytm ścieżki A * (A-Star).
( Wideo Mario A * Bot w akcji )
Moje pytanie brzmi: jak wypada A-Star w porównaniu z Dijkstrą? Patrząc na nie, wydają się podobne.
Dlaczego ktoś miałby używać jednego nad drugim? Zwłaszcza w kontekście pathingu w grach?
Odpowiedzi:
Dijkstra to szczególny przypadek dla A * (gdy heurystyka wynosi zero).
źródło
Dijkstra:
Posiada jedną funkcję kosztów, co jest rzeczywistą wartość kosztów od źródła do każdego węzła:
f(x)=g(x)
.Znajduje najkrótszą ścieżkę od źródła do każdego innego węzła, biorąc pod uwagę tylko rzeczywisty koszt.
Wyszukiwanie:
Ma dwie funkcje kosztowe.
g(x)
: tak samo jak Dijkstra. Rzeczywisty koszt dotarcia do węzłax
.h(x)
: przybliżony koszt od węzłax
do węzła celu. Jest to funkcja heurystyczna. Ta funkcja heurystyczna nigdy nie powinna przeceniać kosztów. Oznacza to, że rzeczywisty koszt dotarcia do węzła docelowego z węzłax
powinien być większy lub równyh(x)
. Nazywa się to dopuszczalną heurystyką.Całkowity koszt każdego węzła jest obliczany według
f(x)=g(x)+h(x)
Wyszukiwanie * rozszerza węzeł tylko wtedy, gdy wydaje się obiecujący. Koncentruje się tylko na dotarciu do węzła docelowego z bieżącego węzła, a nie na dotarciu do wszystkich innych węzłów. Jest optymalne, jeśli dopuszczalna jest funkcja heurystyczna.
Więc jeśli twoja funkcja heurystyczna jest dobra do oszacowania przyszłego kosztu, będziesz musiał zbadać o wiele mniej węzłów niż Dijkstra.
źródło
To, co powiedział poprzedni plakat, a ponadto ponieważ Dijkstra nie ma heurystyki i na każdym kroku wybiera krawędzie przy najmniejszym koszcie, ma tendencję do „zakrywania” większej części wykresu. Z tego powodu Dijkstra może być bardziej przydatny niż A *. Dobrym przykładem jest sytuacja, gdy masz kilka kandydujących węzłów docelowych, ale nie wiesz, który z nich jest najbliższy (w przypadku A * musiałbyś uruchamiać go wiele razy: raz dla każdego kandydującego węzła).
źródło
Algorytm Dijkstry nigdy nie zostałby użyty do odnajdywania ścieżki. Używanie A * nie wymaga myślenia, jeśli możesz wymyślić przyzwoitą heurystykę (zwykle łatwa w grach, szczególnie w światach 2D). W zależności od przestrzeni wyszukiwania, czasami preferowane jest Iteracyjne pogłębianie A *, ponieważ zużywa mniej pamięci.
źródło
Dijkstra to szczególny przypadek dla A *.
Dijkstra znajduje minimalne koszty od węzła początkowego do wszystkich pozostałych. A * znajduje minimalny koszt od węzła początkowego do węzła docelowego.
Algorytm Dijkstry nigdy nie zostałby użyty do znalezienia ścieżki. Używając A * można wymyślić przyzwoitą heurystykę. W zależności od przestrzeni wyszukiwania iteracyjne A * jest preferowane, ponieważ zużywa mniej pamięci.
Kod algorytmu Dijkstry to:
Kod algorytmu A * to:
źródło
Dijkstra znajduje minimalne koszty od węzła początkowego do wszystkich pozostałych. A * znajduje minimalny koszt od węzła początkowego do węzła docelowego.
Dlatego wydawałoby się, że Dijkstra byłaby mniej wydajna, gdy wystarczyłaby minimalna odległość od jednego węzła do drugiego.
źródło
Możesz uznać A * za wersję Dijkstry z przewodnikiem. Oznacza to, że zamiast badać wszystkie węzły, użyjesz heurystyki, aby wybrać kierunek.
Mówiąc bardziej konkretnie, jeśli implementujesz algorytmy z kolejką priorytetów, wówczas priorytet odwiedzanego węzła będzie funkcją kosztu (koszt poprzednich węzłów + koszt uzyskania tutaj) i oszacowania heurystycznego z tego miejsca do celu. Podczas gdy w Dijkstra na priorytet ma wpływ tylko rzeczywisty koszt węzłów. W obu przypadkach kryterium zatrzymania jest osiągnięcie celu.
źródło
Algorytm Dijkstry zdecydowanie znajduje najkrótszą ścieżkę. Z drugiej strony A * zależy od heurystyki. Z tego powodu A * jest szybszy niż algorytm Dijkstry i da dobre wyniki, jeśli masz dobrą heurystykę.
źródło
Jeśli spojrzysz na psuedokod dla Astar:
Natomiast jeśli spojrzeć na to samo dla Dijkstry :
Chodzi więc o to, że Astar nie oceni węzła więcej niż jeden raz,
ponieważ uważa, że wystarczy jedno spojrzenie na węzeł, ze względu
na jego heurystykę.
OTOH, algorytm Dijkstry nie boi się sam korygować, w przypadku
ponownego pojawienia się węzła.
Co powinno sprawić, że Astar będzie szybszy i bardziej odpowiedni do znajdowania ścieżki.
źródło
W A *, dla każdego węzła sprawdzasz połączenia wychodzące pod kątem ich.
Dla każdego nowego węzła obliczasz najniższy do tej pory koszt (csf) w zależności od wagi połączeń do tego węzła i kosztów, jakie musiałeś uzyskać, aby dotrzeć do poprzedniego węzła.
Dodatkowo szacujesz koszt od nowego węzła do węzła docelowego i dodajesz go do csf. Masz teraz szacunkowy koszt całkowity (itp.). (etc = csf + szacowana odległość do celu) Następnie wybierasz z nowych węzłów ten z najniższym itd.
Rób to samo co wcześniej, aż do jednego z nowych węzłów będzie celem.
Dijkstra działa prawie tak samo. Tyle że szacowana odległość do celu wynosi zawsze 0, a algorytm zatrzymuje się najpierw, gdy celem nie jest tylko jeden z nowych węzłów , ale także ten o najniższym csf.
* Jest zwykle szybsze niż dijstra, chociaż nie zawsze tak będzie. W grach wideo często preferujesz podejście „wystarczająco blisko do gry”. Dlatego „dostatecznie blisko” optymalna ścieżka z A * zwykle wystarcza.
źródło
Algorytm Dijkstry jest zdecydowanie kompletny i optymalny, aby zawsze znaleźć najkrótszą ścieżkę. Jednak zwykle trwa to dłużej, ponieważ jest używany głównie do wykrywania wielu węzłów docelowych.
A* search
z drugiej strony ma znaczenie w przypadku wartości heurystycznych, które można zdefiniować, aby zbliżyć się do celu, takich jak odległość między Manhattanem a celem. Może być optymalny lub kompletny, co zależy od czynników heurystycznych. jest zdecydowanie szybszy, jeśli masz pojedynczy węzeł celu.źródło