【问题标题】:"Jumping" in A* searchA* 搜索中的“跳跃”
【发布时间】:2026-02-05 03:25:01
【问题描述】:

我正在尝试实现 A* 搜索算法,这是我的尝试:

void Map::findPath(Robot robot, Model target, vector<Node> nodeList, vector<Node> &closedList) {
Node targetNode = target.getCurrentNode();
Node startNode = robot.getCurrentNode();

vector<Node> openList;

openList.push_back(startNode);
startNode.setG(0);startNode.setH(0);startNode.setF(0);
int i = 0;
while (!openList.empty()) {
    Node currentNode = nodeWithLowestFScore(openList);//always returns the most recent one
    /*for ( int i = 0; i < openList.size(); i++){
        cout << "X: " << openList[i].getX() << " Y: " << openList[i].getY() <<
                " G: " << openList[i].getG() << " M: " << openList[i].getH() << endl;
    }*/

    cout << i++ << ". " << currentNode.getX() << " " << currentNode.getY() << " G: " <<
            currentNode.getG() << " M: " << currentNode.getH() << endl;

    closedList.push_back(currentNode);
    removeFromVector(openList, currentNode);
    if (inVector(closedList, targetNode))
        break;
    vector<Node> adjacentNodes;
    currentNode.getWalkableAdjacentNodes(nodeList, adjacentNodes);
    for ( int i = 0; i < adjacentNodes.size(); i++){
        if (inVector(closedList, adjacentNodes[i]))
            continue;
        if (!inVector(openList, adjacentNodes[i])){
            adjacentNodes[i].setParent(&currentNode);
            adjacentNodes[i].setG(currentNode.getG() +1);//distance is always 1 between adjacent nodes
            adjacentNodes[i].setH(adjacentNodes[i].getDistance(targetNode, 'm'));//heuristic as manhattan
            adjacentNodes[i].setF(adjacentNodes[i].getG() + adjacentNodes[i].getH());
            openList.push_back(adjacentNodes[i]);
        }
        if (inVector(openList, adjacentNodes[i])){//update if it's in the list already
            //?

        }
    }
}

}

我认为函数的名称是不言自明的,所以我不会深入探讨它们。无论如何,在我的示例输出中,我试图从 (x:0, y:-2) 转到 (x:-7, y:6)

  1. 0 -2
  2. -1 -2
  3. -2 -2
  4. -3 -2
  5. -3 -1
  6. -3 0
  7. -4 0
  8. -5 0
  9. -5 1
  10. -5 2
  11. -5 3
  12. -5 4
  13. -6 4
  14. -7 4
  15. -5 5
  16. -5 6
  17. -3 1
  18. -3 2
  19. -3 3
  20. -3 4
  21. -2 4
  22. -2 2
  23. -4 6
  24. -5 7
  25. -8 4
  26. -4 4
  27. -5 -1
  28. -1 -3
  29. 1 -2
  30. 2 -2
  31. -1 -4
  32. -2 -4
  33. -3 -4
  34. -5 -2
  35. -9 4
  36. -9 5
  37. -9 6
  38. -8 6
  39. -7 6

在第 14 行之前一切似乎都很顺利,但随后突然跳转到 (5,5)。 非常感谢任何帮助。

【问题讨论】:

  • 我们是否应该假设您给出的输出与代码中的cout &lt;&lt; i++ &lt;&lt; ". " &lt;&lt; currentNode.getX() &lt;&lt; " " &lt;&lt; currentNode.getY() 相同?
  • 是的,没错。
  • 那么,我们不是按照从 OpenList 中取出节点的顺序来观察的吗?如果是这种情况,这实际上不是一条路径,它只是检查节点的顺序,在这种情况下可能没问题,这取决于启发式,如果地图是完全空的(没有障碍物,或者在沿网格的启发式等)。
  • 正是你所说的:)

标签: c++ algorithm a-star


【解决方案1】:

访问节点的顺序不一定是您的最短路径。据我所知,该算法运行良好。观察到节点 -5 4 在第 12 行被访问,因此 -5 5 只是在第 15 行访问的那个节点的邻居。要获得最短路径,您应该将最终节点的 parentNode 追溯到初始算法结束时的节点。

【讨论】: