A*寻路-如何有效地更新openNodes优先级队列中的节点值? 我有一个C++实现的A*算法,我用向量作为数据结构,我存储了开放节点。每次添加新节点后,我都会对向量进行排序。这太低效了,我被告知要开始使用优先级队列来避免排序

A*寻路-如何有效地更新openNodes优先级队列中的节点值? 我有一个C++实现的A*算法,我用向量作为数据结构,我存储了开放节点。每次添加新节点后,我都会对向量进行排序。这太低效了,我被告知要开始使用优先级队列来避免排序,c++,performance,priority-queue,a-star,C++,Performance,Priority Queue,A Star,优先级队列的问题是,如果我找到一条更好的路径到达已经在openNodes队列中的节点,我需要更新它的F值。队列中的节点按F值排序,但当我更新它时,节点在队列中的位置不会改变。这意味着我可以得到一条次优路径 每当我更改openNodes队列中某个节点的值时,我都尝试通过执行以下模式来解决此问题: 1) 更新节点的F值 2) 在优先级队列中,弹出并临时存储我要查找的节点之前的所有值。弹出并存储该节点 3) 循环遍历节点的临时向量,并将它们推回优先级队列 //...updated the F val

优先级队列的问题是,如果我找到一条更好的路径到达已经在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]);
 }
/…更新了节点的F值
std::向量温度;
//循环条件检查队列顶部的当前节点是否是我正在更新的节点
而(openNodes.top()->getId()!=(*邻居)[i]->getId()){
临时推回(openNodes.top());
openNodes.pop();
}
临时推回(openNodes.top());
openNodes.pop();
对于(int k=0;k

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

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

  • 获取要更新的节点

  • 计算新的F值

  • 它变了吗?不?比你做的还要多

  • 哦!!它真的改变了吗?然后从队列中弹出此节点。(弹出节点不应改变队列已排序的事实。)

  • 遍历整个队列,查看更新的节点所属的位置

  • 在正确的位置插入更新的节点。队列保持排序状态


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

    我基本上是按照你说的去做的,除了4:据我所知,我只能得到队列中最上面的元素。因此,为了能够弹出节点,我需要弹出该节点之前的所有节点。这就是我在发布代码中所做的。弹出所有“挡道”的节点,存储它们,然后将它们推回。事实上,您需要对“最高”以外的项目进行访问(修改访问权限,不少于此),这表明您可能根本不应该使用
    优先级队列
    。。。我想我只需要使用
    向量
    ,然后进行
    部分排序
    第n个元素
    ,以确保第一个元素是最上面的元素。@ravnsgaard是的,这很有意义,谢谢!你认为我也可以像jan.sende建议的那样使用插入排序吗?我查了一下,我认为它能很好地满足我要解决的任务。啊,是的@拉文斯加尔德是对的。我以为你说的是定制队列。如果您使用的是标准库,那么您确实使用了错误的容器类型!