I had a c++ implementation of the A* algorithm and I was using vectors as the data structures in which I stored open nodes. I was sorting the vector after every addition of a new node. That was too inefficient and I was told to start using priority queue to avoid sorting.
The problem I have with priority queue is that if I find a better path to a node that's already in the openNodes queue, I need to update its F value. The nodes in the queue are sorted by the F value, but when I update it, the node's position in the queue doesn't change. This means that I can end up with a sub-optimal path.
I tried to fix this issue by doing the following pattern whenever I would change the value of a node that's in the openNodes queue:
1) Update the F value of the node.
2) In the priority queue, pop and temporarily store all values that are before the node I'm looking for. Pop and store that node as well.
3) Loop through the temporary vector of nodes and push them back into the priority queue.
//...updated the F value of a node
std::vector<Node*> temp;
//the loop condition checks if the current node on top of the queue is the node I'm updating
while (openNodes.top()->getId() != (*neighbours)[i]->getId()) {
temp.push_back(openNodes.top());
openNodes.pop();
}
temp.push_back(openNodes.top());
openNodes.pop();
for (int k = 0; k < temp.size(); k++) {
openNodes.push(temp[k]);
}
This approach does solve the problem of finding a sub-optimal path, but just like in the beginning, it's too inefficient. Is there a better way of solving this? Should I even use priority queue at all?