我有A *算法的c ++实现,并且我使用向量作为存储开放节点的数据结构。每次添加新节点后,我都会对向量进行排序。那太低效了,我被告知要开始使用优先级队列来避免排序。
优先级队列存在的问题是,如果找到到openNodes队列中已经存在的节点的更好路径,则需要更新其F值。队列中的节点按F值排序,但是当我更新它时,节点在队列中的位置不会改变。这意味着我可以得到次优路径。
每当我更改openNodes队列中节点的值时,我都会尝试通过以下模式来解决此问题:
1)更新节点的F值。
2)在优先级队列中,弹出并临时存储我要查找的节点之前的所有值。弹出并存储该节点。
3)循环遍历节点的临时向量,并将其推回到优先级队列中。
//...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]);
}
这种方法确实解决了寻找次优路径的问题,但是就像一开始一样,它的效率太低。有解决这个问题的更好方法吗?我应该完全使用优先级队列吗?
答案 0 :(得分:-1)
我不太了解您的代码示例,但是对我来说,您应该执行以下操作:
获取要更新的节点。
计算新的F值。
它改变了吗?不?比完成还难。
哦!它改变了吗?然后从队列中弹出该节点。 (弹出节点不应更改您的队列已被排序的事实。)
遍历整个队列,查找更新的节点所属的位置。
在正确的位置插入更新的节点。队列保持排序。
如果您在这里看不到它,您需要的是插入排序!