Algoritmos de búsqueda de ruta?

24

Publiqué esta pregunta en el desbordamiento de pila primero, pero supongo que nadie está muy interesado en los videojuegos allí ...

¿Cuáles son algunos algoritmos de búsqueda de ruta utilizados en juegos de todo tipo? (De todos los tipos donde los personajes se mueven, de todos modos) ¿Se usa mucho Dijkstra? Creo que no, ya que en realidad no traza los pasos a seguir para llegar a algún lado, ¿verdad? Si lo entiendo bien, solo determina qué objeto es el más cercano. Realmente no estoy buscando codificar nada; solo investigando un poco, aunque si pega el seudocódigo o algo así, estaría bien (puedo entender Java y C ++). Básicamente estoy buscando una descripción rápida de la búsqueda de rutas en general.

Sé que A * es como EL algoritmo para usar en juegos 2D. Eso es genial y todo eso, pero ¿qué pasa con los juegos 2D que no están basados ​​en cuadrícula? Cosas como Age of Empires o Link's Awakening. No hay espacios cuadrados distintos para navegar, entonces, ¿qué hacen?

¿Qué hacen los juegos 3D? He leído esta cosita http://www.ai-blog.net/archives/000152.html , que según tengo entendido es una gran autoridad en el tema, pero en realidad no explica CÓMO, una vez que se establecen las mallas, La búsqueda del camino está hecha. SI A * es lo que usan, ¿cómo se hace algo así en un entorno 3D? ¿Y cómo funcionan exactamente las splines para redondear esquinas?

Pojo
fuente
2
Creo que esta pregunta es demasiado abierta para el formato de preguntas y respuestas de SE. Preguntas frecuentes
John McDonald
1
Los juegos que mencionaste deben dividir el mapa en nodos para A * de una forma u otra. Ese proceso de descomposición no tiene que involucrar cuadrículas cuadradas y hay muchas formas de hacerlo. Mira este video youtube.com/watch?v=nGC_kBCoHYc , un buen juego lo hace para que los jugadores no puedan decir lo que son en realidad haciendo detrás de escena.
XiaoChuan Yu
1
Hay muchas preguntas aquí, así que realmente no puedo escribir una respuesta, pero notaré que Dijkstra devuelve una ruta, y la mayoría de los algoritmos de búsqueda de ruta son multipropósito. Convierte su mundo, 2D o 3D, en un gráfico conectado y ejecuta un algoritmo de búsqueda de ruta en él.
Gregory Avery-Weir
Solo como referencia: respondí la pregunta en Stack Overflow .
Juliano
1
Permíteme despotricar. Esta pregunta obtuvo 4 votos a favor en SO, en comparación con 4 votos cercanos aquí en GDSE. No puedo evitar sentir que los moderadores en este sitio son demasiado agresivos. Claro, puedo ver cómo la pregunta va en contra de las pautas especificadas en las Preguntas frecuentes, pero citando, esas pautas están en su lugar para evitar diminishing the usefulness of our site. Esta pregunta ya ha sido favorecida 3 veces, lo que demuestra que ha sido útil para algunos usuarios. Por lo tanto, no puedo evitar sentir que votar para cerrarlo y arriesgar una eventual eliminación es mucho más contraproducente.
David Gouveia

Respuestas:

62

Demasiadas preguntas a la vez, por lo que es difícil dar una respuesta concreta, pero discutir algunos de estos temas. Dividiré la respuesta en dos e intentaré abordarla lo mejor que pueda. No afirmo que ninguna de estas listas esté completa , pero son algunos de los diferentes métodos que recuerdo.


Parte 1 - Algoritmos de Pathfinding

Para empezar, hay muchas formas de implementar la búsqueda de rutas, pero no todas devuelven la ruta más corta, o son eficientes o incluso confiables. Por ejemplo:

  • Métodos primitivos que no "miran hacia el futuro" y dan un paso a la vez:

    • Retroceso aleatorio: dé un paso a la vez en la dirección de la meta. Si se encuentra un obstáculo, trate de evitarlo retrocediendo un poco en una dirección aleatoria y luego intente nuevamente. No es confiable en absoluto y se quedará atascado en una multitud de situaciones.

    • Rastreo de obstáculos : otro enfoque, similar al retroceso aleatorio, pero en lugar de retroceder aleatoriamente, comience a rastrear alrededor del objeto una vez que se encuentre una colisión, como si tuviera la mano derecha pegada a la pared y tuviera que moverse tocándola. Una vez que no haya colisión, continúe moviéndose en la dirección de la meta. Una vez más puede quedar atrapado en muchas situaciones.

  • Métodos que miran hacia el futuro para encontrar todo el camino a la vez:

    • Breadth First Search - Recorrido gráfico simple al visitar cada capa de niños a la vez, detenerse cuando se encuentra la ruta. Si el gráfico no está ponderado (es decir, la distancia entre cada nodo adyacente es siempre la misma), encuentra la ruta más corta, aunque no demasiado eficiente. Para gráficos ponderados, puede que no devuelva el camino más corto, pero siempre encontrará uno si existe.

    • Búsqueda en profundidad primero : otra forma de atravesar un gráfico, pero en lugar de tomarla capa por capa, el algoritmo intenta buscar primero en el gráfico. Este método puede tener problemas si la profundidad de la búsqueda no está limitada, especialmente cuando se usa una implementación recursiva, lo que puede conducir a un desbordamiento de la pila, por lo que generalmente es más seguro implementarla iterativamente usando una pila.

    • Mejor primera búsqueda : similar a Breadth First Search pero utiliza una heurística que elige primero al vecino más prometedor. La ruta devuelta puede no ser la más corta, pero es más rápida de ejecutar que la primera búsqueda de amplitud. A * es un tipo de Mejor primera búsqueda.

    • Método de Dijkstra : realiza un seguimiento del costo total desde el inicio hasta cada nodo que se visita y lo utiliza para determinar el mejor orden para atravesar el gráfico. Funciona con gráficos ponderados y devuelve el camino más corto, pero puede implicar mucha búsqueda.

    • A * : similar a Dijkstra, pero también utiliza una heurística para estimar la probabilidad de que cada nodo esté cerca de la meta, para tomar la mejor decisión. Debido a esta heurística, A * encuentra el camino más corto en un gráfico ponderado de una manera mucho más oportuna.

  • Luego, hay variaciones de A * (u optimizaciones de pathfinding en general) que lo hacen más rápido o más adaptado a ciertas circunstancias, tales como (vea la respuesta relacionada y una lista completa en cstheory.SE ):

    • LPA * : similar a A * pero puede recalcular más rápidamente la mejor ruta cuando se realiza un pequeño cambio en el gráfico
    • D * Lite : basado en LPA *, hace lo mismo, pero supone que el "punto de inicio" es una unidad que se mueve hacia el final mientras se realizan cambios en el gráfico
    • HPA * (jerárquico) : utiliza varias capas en diferentes niveles de abstracción para acelerar la búsqueda. Por ejemplo, una capa de nivel superior puede simplemente conectar habitaciones, mientras que una capa de nivel inferior se encarga de evitar obstáculos.
    • IDA * (profundización iterativa) : reduce el uso de memoria en comparación con A * normal mediante el uso de profundización iterativa.
    • SMA * (memoria simplificada) : solo utiliza la memoria disponible para realizar la búsqueda.
    • Búsqueda de punto de salto - ¡Créditos a Eric en los comentarios por mencionarlo! Acelera la búsqueda de rutas en mapas de cuadrícula de costo uniforme ( enlace ).

Parte 2 - Representación del espacio de búsqueda

Y finalmente para abordar esta pregunta:

Sé que A * es como EL algoritmo para usar en juegos 2D. Eso es genial y todo eso, pero ¿qué pasa con los juegos 2D que no están basados ​​en cuadrícula?

¡Dos grandes conceptos erróneos aquí! De hecho:

  1. A * no le importa si el juego es 2D o 3D, y es igualmente apropiado para ambos casos.
  2. A * funciona bajo cualquier representación gráfica, por lo que no le importa si el mundo es una cuadrícula o no.

Entonces, si el mundo no necesita ser una cuadrícula, ¿de qué otras maneras puedes representarlo? Aquí hay una breve descripción de las formas de particionar el espacio mundial para la búsqueda de caminos, y la mayoría de estos funcionan tanto para 2D como para 3D:

  • Cuadrícula rectangular : divida el mundo en una cuadrícula regular de cuadrados con cada celda de la cuadrícula como un nodo en el gráfico, y la conexión entre dos nodos sin obstáculos es un borde.

    ingrese la descripción de la imagen aquí

  • Quadtree : otra forma de dividir el espacio, pero en lugar de dividir en una cuadrícula de celdas de tamaño regular, dividir en cuatro, luego dividir recursivamente cada uno de estos en cuatro nuevamente. Agregar una tercera dimensión lo convierte en un octree .

    ingrese la descripción de la imagen aquí

  • Polígonos convexos : dividir el área transitable en una malla de polígonos convexos interconectados. Cada polígono se convierte en un nodo, y los bordes compartidos son los bordes del gráfico. Estos pueden ser triángulos, por ejemplo, y a veces incluso pueden ser una malla creada por un artista al crear los activos de nivel. A menudo se denomina malla de navegación . Ver este enlace . Aquí hay un conjunto de herramientas de construcción de malla de navegación muy popular: Recast .

    ingrese la descripción de la imagen aquí

  • Puntos de visibilidad : la forma más común es colocar un nodo justo fuera de cada vértice convexo del obstáculo, y luego conectar cada par de nodos que pueden verse entre sí. Mira este enlace . Sin embargo, los nodos no tienen que ser los vértices, y el diseñador puede colocarlos manualmente en el mapa. En ese caso, el sistema se conoce con frecuencia como un gráfico de waypoint .

    ingrese la descripción de la imagen aquí

David Gouveia
fuente
1
Dos enlaces: 1) Mikko Mononen ha realizado el trabajo de búsqueda de ruta Killzone 3 , y tiene un blog muy agradable donde documenta el proceso de desarrollo de Recast (generador de navmesh) y Detour (kit de herramientas de búsqueda de ruta), ambos bajo licencia MIT y utilizados, por ejemplo en Kingdoms of Amalur: Reckoning . 2) La búsqueda de puntos de salto es, creo, uno de los mayores desarrollos recientes en la búsqueda de rutas basadas en la cuadrícula.
Eric