A *(星)算法:理解f / g / h分数

时间:2017-03-19 09:16:44

标签: algorithm path-finding a-star

我正在尝试用Java实现A *算法,但我不确定我是否正确理解了f / g / h分数。我正在帮助自己pseudocode of A* on Wikipedia。这是一个伪代码:

while openSet is not empty
    current := the node in openSet having the lowest fScore[] value
    if current = goal
        return reconstruct_path(cameFrom, current)

    openSet.Remove(current)
    closedSet.Add(current)
    for each neighbor of current
        if neighbor in closedSet
            continue        // Ignore the neighbor which is already evaluated.
        // The distance from start to a neighbor
        tentative_gScore := gScore[current] + dist_between(current, neighbor)
        if neighbor not in openSet  // Discover a new node
            openSet.Add(neighbor)
        else if tentative_gScore >= gScore[neighbor]
            continue        // This is not a better path.

        // This path is the best until now. Record it!
        cameFrom[neighbor] := current
        gScore[neighbor] := tentative_gScore
        fScore[neighbor] := gScore[neighbor] + heuristic_cost_estimate(neighbor, goal)

return failure

我不明白的是这一部分:

else if tentative_gScore >= gScore[neighbor]
        continue        // This is not a better path.

为什么邻居已经有G分?我正在以这种方式解释算法:

  1. 从具有最低F分数的开放集中选择一个节点。 (F分数= G分数+ H分数,其中G分数是从开始到当前节点的当前路径的成本(我们将从开放集合中选择的路径),H分数是当前节点的成本(我们要选择的那个)到终点节点,假设我们选择了启发式的曼哈顿距离。)

  2. 然后,检查我们刚刚选择的节点的所有邻居(当前节点)。

  3. 如果它已经在关闭的集合中,请跳过它。如果不是,请检查它是否在开放集中。如果不是,则计算该邻居的F得分,其中G得分现在是当前节点的G得分+从当前到邻居的G得分。这就是我提供的代码中所谓的tentative_gScore。 H得分更改为从邻居到终端节点计算的值。

  4. 以下是问题:

    什么是gScore [邻居]?它在哪里计算?它的价值是什么? Tentative_gScore我明白了,但是我们从哪里获得邻居的gScore,以便我们可以测试条件:

     else if tentative_gScore >= gScore[neighbor]
            continue        // This is not a better path.
    

1 个答案:

答案 0 :(得分:2)

好的,我明白了。

如果第一次找到邻居,你甚至不比较g分数,只需将其添加到开放集中即可。

如果邻居已经在开放集中(这也意味着它有某种g分数): gScore [邻居]是添加到开放集中的先前找到的邻居的g分数。如果再次找到此邻居,则可以比较g分数(新g分数与旧g分数(之前找到))。如果新分数更好(即更低),则相应地更改分数和父节点。

这很简单。 :)