A*寻路-如何有效地更新openNodes优先级队列中的节点值? 我有一个C++实现的A*算法,我用向量作为数据结构,我存储了开放节点。每次添加新节点后,我都会对向量进行排序。这太低效了,我被告知要开始使用优先级队列来避免排序
优先级队列的问题是,如果我找到一条更好的路径到达已经在openNodes队列中的节点,我需要更新它的F值。队列中的节点按F值排序,但当我更新它时,节点在队列中的位置不会改变。这意味着我可以得到一条次优路径 每当我更改openNodes队列中某个节点的值时,我都尝试通过执行以下模式来解决此问题: 1) 更新节点的F值 2) 在优先级队列中,弹出并临时存储我要查找的节点之前的所有值。弹出并存储该节点 3) 循环遍历节点的临时向量,并将它们推回优先级队列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
//...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
这种方法确实解决了寻找次优路径的问题,但与开始时一样,它效率太低。有没有更好的办法解决这个问题?我甚至应该使用优先级队列吗?我不太理解您的代码示例,但对我来说,听起来您应该执行以下操作:
如果您没有在这里看到它,您需要的是插入排序 我基本上是按照你说的去做的,除了4:据我所知,我只能得到队列中最上面的元素。因此,为了能够弹出节点,我需要弹出该节点之前的所有节点。这就是我在发布代码中所做的。弹出所有“挡道”的节点,存储它们,然后将它们推回。事实上,您需要对“最高”以外的项目进行访问(修改访问权限,不少于此),这表明您可能根本不应该使用
优先级队列
。。。我想我只需要使用向量
,然后进行部分排序
或第n个元素
,以确保第一个元素是最上面的元素。@ravnsgaard是的,这很有意义,谢谢!你认为我也可以像jan.sende建议的那样使用插入排序吗?我查了一下,我认为它能很好地满足我要解决的任务。啊,是的@拉文斯加尔德是对的。我以为你说的是定制队列。如果您使用的是标准库,那么您确实使用了错误的容器类型!