我对改变A *算法中节点的父节点感到困惑。 似乎有不同的选择新父母的方式:
在此视频中: https://www.youtube.com/watch?v=KNXfSOx4eEE
它说你应该检查一下:
G cost currentNode + movement cost from currentNode <= G cost openListNode
如果是这种情况,那么我们应该将openListNode的父节点替换为当前节点。
但是在这个实现中: http://www.codebytes.in/2015/02/a-shortest-path-finding-algorithm.html
它有以下代码:
static void checkAndUpdateCost(Cell current, Cell t, int cost){
if(t == null || closed[t.i][t.j])return;
int t_final_cost = t.heuristicCost+cost;
boolean inOpen = open.contains(t);
if(!inOpen || t_final_cost<t.finalCost){
t.finalCost = t_final_cost;
t.parent = current;
if(!inOpen)open.add(t);
}
}
它检查最终成本:G + H,这与其他解释相矛盾,因为它应该只是G成本,而不是G成本和启发式的总和。
有人可以解释一下,哪一个是正确的?,实施是错误的吗?
答案 0 :(得分:1)
底线前线(BLUF):
视频是准确的,但这里的关键是:节点的父节点只能在以下两种情况之一中更新:1。)第一次遇到节点时,或者2 。)当您找到以前遇到的节点的更有效路径时。此外,在更新节点的父节点时不要使用启发式方法。
其他详细信息:
以下是基于Wikipedia's Pseudocode的工作实施方案;我已经添加了额外的评论来区分这两种情况。
如果!isOpen && !isClosed
为true
,则之前从未见过该节点;因此,它的父节点应该设置为当前节点,并且它应该被添加到开放集合中。但是如果!isOpen && !isClosed
是false
,那么节点已经在开放集中(即如果isOpen
为真)或者之前已关闭(即如果isClosed
为真)。因此,我们需要检查当前路径是否比先前导致邻居节点处于打开/关闭集合的路径更有效 - 这就是我们检查costFromStart < g_score[neighborNode.x][neighborNode.y]
while (!openList.isEmpty()) {
Pair node = openList.dequeueMin().getValue();
if (node.equals(goal)) {
// construct the path from start to goal
return reconstruct_path(goal);
}
for (Pair neighborNode : getNeighbors(node,goal)) {
if (neighborNode == null) continue;
boolean isOpen = openSet.contains(neighborNode);
boolean isClosed = closedSet.contains(neighborNode);
double costFromStart = g_score[node.x][node.y]+MOVEMENT_COST;
// check if the neighbor node has not been
// traversed or if a shorter path to this
// neighbor node is found.
if (
(!isOpen && !isClosed) // first time node has been encountered
|| //or
costFromStart < g_score[neighborNode.x][neighborNode.y]) //new path is more efficient
{
came_from[neighborNode.x][neighborNode.y] = node;
g_score[neighborNode.x][neighborNode.y] = costFromStart;
h_score[neighborNode.x][neighborNode.y] =
estimateCost(neighborNode,goal);
if (isClosed) {
closedSet.remove(neighborNode);
}
if (!isOpen) {
openList.enqueue(neighborNode,costFromStart);
openSet.add(neighborNode);
}
}
}
closedSet.add(node);
}