A *算法更改节点父节点

时间:2016-08-20 13:47:38

标签: java algorithm implementation a-star

我对改变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成本和启发式的总和。

有人可以解释一下,哪一个是正确的?,实施是错误的吗?

1 个答案:

答案 0 :(得分:1)

底线前线(BLUF):

视频是准确的,但这里的关键是:节点的父节点只能在以下两种情况之一中更新:1。)第一次遇到节点时,或者2 。)当您找到以前遇到的节点的更有效路径时。此外,在更新节点的父节点时不要使用启发式方法。

其他详细信息:

以下是基于Wikipedia's Pseudocode的工作实施方案;我已经添加了额外的评论来区分这两种情况。

如果!isOpen && !isClosedtrue,则之前从未见过该节点;因此,它的父节点应该设置为当前节点,并且它应该被添加到开放集合中。但是如果!isOpen && !isClosedfalse,那么节点已经在开放集中(即如果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);
}