Estaba mirando lo que los muchachos en la competencia Mario AI han estado haciendo y algunos de ellos han construido algunos robots de Mario bastante buenos utilizando el algoritmo de ruta A * (A-Star).
( Video de Mario A * Bot en acción )
Mi pregunta es, ¿cómo se compara A-Star con Dijkstra? Mirándolos, parecen similares.
¿Por qué alguien usaría uno sobre el otro? ¿Especialmente en el contexto de la ruta en los juegos?
Respuestas:
Dijkstra es un caso especial para A * (cuando la heurística es cero).
fuente
Dijkstra:
Tiene una función de coste, que es valor coste real de la fuente a cada nodo:
f(x)=g(x)
.Encuentra la ruta más corta desde el origen hasta todos los demás nodos considerando solo el costo real.
Una búsqueda:
Tiene dos funciones de costo.
g(x)
: igual que Dijkstra. El costo real para llegar a un nodox
.h(x)
: costo aproximado de nodox
a nodo objetivo. Es una función heurística. Esta función heurística nunca debe sobreestimar el costo. Eso significa que el costo real para alcanzar el objetivo de nodo a nodox
debe ser mayor o igualh(x)
. Se llama heurística admisible.El costo total de cada nodo se calcula mediante
f(x)=g(x)+h(x)
Una búsqueda * solo expande un nodo si parece prometedor. Solo se enfoca para alcanzar el nodo objetivo desde el nodo actual, no para alcanzar todos los demás nodos. Es óptimo, si la función heurística es admisible.
Entonces, si su función heurística es buena para aproximar el costo futuro, entonces necesitará explorar muchos menos nodos que Dijkstra.
fuente
Lo que decía el póster anterior, además porque Dijkstra no tiene heurística y en cada paso escoge bordes con el menor costo, tiende a "cubrir" más de su gráfico. Debido a eso, Dijkstra podría ser más útil que A *. Un buen ejemplo es cuando tiene varios nodos objetivo candidatos, pero no sabe cuál es el más cercano (en el caso A *, tendría que ejecutarlo varias veces: una vez para cada nodo candidato).
fuente
El algoritmo de Dijkstra nunca se usaría para encontrar rutas. El uso de A * es obvio si puedes encontrar una heurística decente (generalmente fácil para juegos, especialmente en mundos 2D). Dependiendo del espacio de búsqueda, a veces es preferible la profundización iterativa A * porque usa menos memoria.
fuente
Dijkstra es un caso especial para A *.
Dijkstra encuentra los costos mínimos desde el nodo inicial hasta todos los demás. A * encuentra el costo mínimo desde el nodo inicial hasta el nodo objetivo.
El algoritmo de Dijkstra nunca se usaría para encontrar el camino. Usar A * one puede llegar a una heurística decente. Dependiendo del espacio de búsqueda, es preferible A * iterativo porque usa menos memoria.
El código para el algoritmo de Dijkstra es:
El código para el algoritmo A * es:
fuente
Dijkstra encuentra los costos mínimos desde el nodo inicial hasta todos los demás. A * encuentra el costo mínimo desde el nodo inicial hasta el nodo objetivo.
Por lo tanto, parecería que Dijkstra sería menos eficiente cuando todo lo que necesita es la distancia mínima de un nodo a otro.
fuente
Puede considerar A * una versión guiada de Dijkstra. Es decir, en lugar de explorar todos los nodos, utilizará una heurística para elegir una dirección.
Para decirlo más concretamente, si está implementando los algoritmos con una cola de prioridad, entonces la prioridad del nodo que está visitando será una función del costo (costo de nodos anteriores + costo para llegar aquí) y la estimación heurística desde aquí a la meta. Mientras que en Dijkstra, la prioridad solo está influenciada por el costo real para los nodos. En cualquier caso, el criterio de detención es alcanzar la meta.
fuente
El algoritmo de Dijkstra encuentra el camino más corto definitivamente. Por otro lado, A * depende de la heurística. Por esta razón, A * es más rápido que el algoritmo de Dijkstra y dará buenos resultados si tiene una buena heurística.
fuente
Si nos fijamos en el psuedocode de Astar:
Mientras que, si nos fijamos en lo mismo para Dijkstra :
Entonces, el punto es que Astar no evaluará un nodo más de una vez,
ya que cree que mirar un nodo una vez es suficiente, debido
a su heurística.
OTOH, el algoritmo de Dijkstra no es tímido para corregirse, en caso de
que aparezca un nodo nuevamente.
Lo que debería hacer que Astar sea más rápido y más adecuado para encontrar rutas.
fuente
En A *, para cada nodo verifica las conexiones salientes para sus.
Para cada nuevo nodo, calcula el costo más bajo hasta ahora (csf) dependiendo de los pesos de las conexiones a este nodo y los costos que tuvo que alcanzar el nodo anterior.
Además, estima el costo desde el nuevo nodo hasta el nodo de destino y agrega esto al csf. Ahora tiene el costo total estimado (etc.). (etc = csf + distancia estimada al objetivo) A continuación, elija entre los nuevos nodos el que tenga el más bajo, etc.
Haga lo mismo que antes hasta que uno de los nuevos nodos sea el objetivo.
Dijkstra funciona casi igual. Excepto que la distancia estimada al objetivo siempre es 0, y el algoritmo se detiene primero cuando el objetivo no es solo uno de los nuevos nodos , sino también el que tiene el csf más bajo.
A * suele ser más rápido que dijstra, aunque este no siempre será el caso. En los videojuegos, a menudo prefieres el enfoque de "lo suficientemente cerca para un juego". Por lo tanto, la ruta óptima "lo suficientemente cerca" de A * generalmente es suficiente.
fuente
El algoritmo de Dijkstra es definitivamente completo y óptimo para que siempre encuentre el camino más corto. Sin embargo, tiende a tomar más tiempo ya que se usa principalmente para detectar múltiples nodos de objetivo.
A* search
por otro lado, importa con valores heurísticos, que puede definir para alcanzar su objetivo más cerca, como la distancia de Manhattan hacia el objetivo. Puede ser óptimo o completo, lo que depende de factores heurísticos. definitivamente es más rápido si tiene un nodo de objetivo único.fuente