2012-09-03 8 views
7

Estoy desarrollando un A * por primera vez, y estaba usando una priority_queue para el conjunto abierto, hasta que me doy cuenta de que necesita verificar si los nodos están también en el conjunto abierto, no solo en el cercano.A * ¿cuál es la mejor estructura de datos para el conjunto abierto?

La cosa es que no se puede iterar sobre una cola de prioridad ... ¿Por qué todos recomiendan una cola de prioridad para el conjunto abierto? ¿Todavía es la mejor opción? Creo que la única forma de iterar es haciendo una copia para poder sacar todo (enorme costo).

¿Cuál es la mejor estructura de datos para usar en A *?

+2

http://stackoverflow.com/questions/11912736/c-a-star-implementation-determining-whether-a-node-is-already-in-the-priori – Rost

+0

@Rost ha .. que partido – Icebone1000

Respuesta

7

Una cola de prioridad (PQ) es una estructura de datos abstracta (ADS). Hay muchas posibilidades para implementarlos. Desafortunadamente, la prioridad_queue suministrada con la biblioteca estándar de C++ es bastante limitada, y otras implementaciones son mucho mejores para implementar A *. Spoilers: puede usar std :: set/multiset en lugar de std :: priority_queue. Pero sigue leyendo:

Entonces, ¿qué es lo que necesita de la cola de prioridad para implementar A * es:

  1. Consigue el nodo con el menor coste
  2. disminuir los costos de elementos arbitrarios

Cualquier cola de prioridad puede hacer 1., pero para 2., necesita una cola de prioridad "mutable". El Standard-Lib no puede hacer esto. Además, necesita una forma fácil de encontrar entradas en la cola de prioridad, para averiguar dónde disminuir las teclas (para cuando A * encuentre una mejor ruta a un nodo ya abierto). Hay dos formas básicas de hacerlo: almacena un identificador en el elemento de cola de prioridad dentro de su nodo de gráfico (o usa un mapa para almacenar esos identificadores para cada nodo de gráfico) o inserta los nodos de gráfico en sí.

Para el primer caso, donde almacena identificadores para cada nodo, puede usar std :: multiset para su cola de prioridad. std :: multiset :: first() siempre será su clave de "menor costo", y puede disminuir una clave quitándola del conjunto, cambiando el valor y volviendo a insertar, y actualizando el identificador. Alternativamente, puede usar las colas de prioridad mutables de Boost.Heap, que soportan directamente "disminuir clave".

Para el segundo caso, necesitaría algún tipo de árbol binario "intrusivo", ya que los nodos de pathfinding deben estar en la cola de prioridad. Si no desea hacer su propia versión, consulte los contenedores asociativos ordenados en Boost.Intrusive.

3

El sujeto es muy grande, le sugiero que leer esta página si desea conocer las diferentes posibilidades y tener una buena comprensión de lo que la estructura de datos está adaptada a su situación: http://theory.stanford.edu/~amitp/GameProgramming/ImplementationNotes.html#set-representation

En mi caso, el El montón binario era un buen equilibrio entre la dificultad de implementación y las actuaciones, que era totalmente lo que estaba buscando. ¿Pero tal vez estás buscando algo diferente?

El resto del documento es una muy buena referencia para A * para el desarrollo del juego http://theory.stanford.edu/~amitp/GameProgramming/index.html

-1

Significan una cola de prioridad no necesariamente la clase std :: priority_queue que viene con el idioma. Si el integrado no hace lo que necesita, escriba el suyo o encuentre otro.

Cuestiones relacionadas