Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A* whats the best data structure for the open set?

Im developing an A* for the first time, and I was using a priority_queue for the open set, until I realize you need to check if nodes are in the open set too, not just the close one.

Thing is, you cant iterate over a priority queue..So why everyone recommend a priority queue for the open set? Is it yet the best option? I think the only way to iterate over it is making a copy so I can pop everything from it (enormous cost).

What the best data structure to use on A*?

like image 440
Icebone1000 Avatar asked Sep 03 '12 20:09

Icebone1000


People also ask

Which data structure is used for a star?

We can use any data structure to implement open list and closed list but for best performance, we use a set data structure of C++ STL(implemented as Red-Black Tree) and a boolean hash table for a closed list.

Which is the best data structure?

An array is the simplest and most widely used data structure. Other data structures like stacks and queues are derived from arrays.

What are the 4 data structures?

When we think of data structures, there are generally four forms: Linear: arrays, lists. Tree: binary, heaps, space partitioning etc. Hash: distributed hash table, hash tree etc.

What is the best data structure type to store a number?

Explanation: The only two choices that make sense are Array and Linked List.


1 Answers

A priority queue (PQ) is an abstract data structure (ADS). There are many possibilities to implement them. Unfortunately, the priority_queue supplied with the C++ standard library is rather limited, and other implementations are suited a lot better for implementing A*. Spoilers: you can use std::set/multiset instead of std::priority_queue. But read on:

So what do you need from the priority queue to implement A* is:

  1. Get the node with the lowest cost
  2. Decrease the costs of arbitrary elements

Any priority queue can do 1., but for 2., you need a "mutable" priority queue. The Standard-Lib one cannot do this. Also, you need an easy way to find entries in the priority queue, to find out where to decrease the keys (For when A* finds a better path to an already opened node). There are two basic ways for this: You store a handle to the priority queue element within your graph node (or use a map to store those handles for each graph node) - or you insert the graph nodes themselves.

For the first case, where you store handles for each node, you can use std::multiset for your priority queue. std::multiset::first() will always be your "lowest cost" key, and you can decrease a key by removing it from the set, changing the value and re-inserting, and updating the handle. Alternatively, you can use the mutable priority queues from Boost.Heap, which directly support "decrease-key".

For the second case, you would need some kind of "intrusive" binary tree - since your pathfinding nodes themselves need to be in the priority queue. If you don't want to roll your own, see the ordered associative containers in Boost.Intrusive.

like image 146
ltjax Avatar answered Sep 26 '22 22:09

ltjax