A *寻路-如何有效地更新openNodes优先级队列中的节点值?

时间:2018-07-27 15:28:33

标签: c++ performance priority-queue a-star

我有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]);
 }

这种方法确实解决了寻找次优路径的问题,但是就像一开始一样,它的效率太低。有解决这个问题的更好方法吗?我应该完全使用优先级队列吗?

1 个答案:

答案 0 :(得分:-1)

我不太了解您的代码示例,但是对我来说,您应该执行以下操作:

  1. 获取要更新的节点。

  2. 计算新的F值。

  3. 它改变了吗?不?比完成还难。

  4. 哦!它改变了吗?然后从队列中弹出该节点。 (弹出节点不应更改您的队列已被排序的事实。)

  5. 遍历整个队列,查找更新的节点所属的位置。

  6. 在正确的位置插入更新的节点。队列保持排序。

如果您在这里看不到它,您需要的是插入排序