【问题标题】:Flawed logic in A* implementationA* 实现中的错误逻辑
【发布时间】:2014-04-29 20:07:53
【问题描述】:

我一直在使用其他人的 A* 寻路算法实现示例作为拐杖来帮助我编写我的第一个实现。在我发现的一个更易读的示例中,我遇到了一些逻辑问题。

我不是来挑选这段代码的,真的,我想弄清楚我是否正确,或者我是否误解了这里的机制。如果我需要查看 A * 我会工作,但如果这段代码不正确,我需要寻找其他资源来学习。

在我看来,这里发现的逻辑在两个地方有缺陷都包含在这里:

for(Node neighbor : current.getNeighborList()) {
    neighborIsBetter;
    //if we have already searched this Node, don't bother and continue to the next 
    if (closedList.contains(neighbor))
        continue;

    //also just continue if the neighbor is an obstacle
    if (!neighbor.isObstacle) {

        // calculate how long the path is if we choose this neighbor as the next step in the path 
        float neighborDistanceFromStart = (current.getDistanceFromStart() + map.getDistanceBetween(current, neighbor));

        //add neighbor to the open list if it is not there
        if(!openList.contains(neighbor)) {
-->         openList.add(neighbor);
            neighborIsBetter = true;
            //if neighbor is closer to start it could also be better
-->     } else if(neighborDistanceFromStart < current.getDistanceFromStart()) {
            neighborIsBetter = true;
        } else {
            neighborIsBetter = false;
        }
        // set neighbors parameters if it is better
        if (neighborIsBetter) {
            neighbor.setPreviousNode(current);
            neighbor.setDistanceFromStart(neighborDistanceFromStart);
            neighbor.setHeuristicDistanceFromGoal(heuristic.getEstimatedDistanceToGoal(neighbor.getX(), neighbor.getY(), map.getGoalLocationX(), map.getGoalLocationY()));
        }
    }
}

source

我标记的第一行 (-->) 对我来说似乎不正确。如果您查看implementation of the list being used(下方),它会根据heuristicDistanceFromGoal 进行排序,.add 下方设置了几行。

public int compareTo(Node otherNode) {
    float thisTotalDistanceFromGoal = heuristicDistanceFromGoal + distanceFromStart;
    float otherTotalDistanceFromGoal = otherNode.getHeuristicDistanceFromGoal() + otherNode.getDistanceFromStart();

    if (thisTotalDistanceFromGoal < otherTotalDistanceFromGoal) {
        return -1;
    } else if (thisTotalDistanceFromGoal > otherTotalDistanceFromGoal) {
        return 1;
    } else {
        return 0;
    }
}

我标记的第二行应始终评估为 false。上面写着:

} else if(neighborDistanceFromStart &lt; current.getDistanceFromStart()) {

可以简化为:

if((current.getDistanceFromStart() + map.getDistanceBetween(current, neighbor)) < current.getDistanceFromStart())

再次:

if(map.getDistanceBetween(current, neighbor) &lt; 0)

除了getDistanceBetween() 应该总是返回一个正值 (see here) 之外,这很好。

我是在轨道上还是偏离轨道?

【问题讨论】:

  • StackOverflow 专为遇到代码问题并获得修复帮助的用户而设计。这里不是讨论其他人代码的地方。
  • 也许我需要重新构建问题。本质上,我不在乎这个人的代码是否合乎逻辑。我真的很想知道我是否理解A*。由于我认为我这样做并且这对我来说看起来不太正确(但看起来并不完全错误),所以我试图找出我是否感到困惑或步入正轨。
  • 起初你会有一个定义地图的数据结构,但是你使用另一个数据结构来保存你当前位置的近邻,如果邻居不在列表中,添加它,如果查看邻居值是否小于当前值,如果邻居比您当前的位置好,则将布尔值分配为 true 并尝试将其设为新位置。但是是的,我想你确实提出了一个很好的问题,但是有一个部分专门用于代码审查
  • @tommyknocker 代码审查只允许对发帖人自己编写的代码提出问题。它也只允许对被认为正确的代码提出问题。
  • 我对这些 A* 启发式一无所知,所以我想我读过它 here。我将“欧几里得距离平方”下的内容与ClosestHeuristic.java 进行了比较。文章说“不要使用”,但据我所知,它正在被使用。我认为你正在做某事......

标签: java graph-algorithm path-finding


【解决方案1】:

首先,您大部分时间都在轨道上。我强烈怀疑您发布的代码仍在开发中并且存在一些问题。但是,您对距离的假设仍然是积极的,一般来说是不正确的。 A* 是一种图搜索算法,通常边也可以具有负权重。因此,我假设他们试图实现最一般的情况。不过,openList.add 对我来说似乎完全没问题。您的队列应该使用启发式距离进行排序。只需检查 wiki 页面https://en.wikipedia.org/wiki/A_star,相关行是 f_score[neighbor] := g_score[neighbor] + heuristic_cost_estimate(neighbor, goal)。而且,这背后的主要思想是,你总是低估距离(可接受的启发式);因此,如果找到目标,则没有一个未探索的节点是最优的。你可以在http://en.wikipedia.org/wiki/Admissible_heuristic阅读更多内容

其次,如果你想要一个稳定的人工智能代码库,你可以简单地使用http://code.google.com/p/aima-java/。它是AIMA(Artificial Intelligence A Modern Approach)中算法的实现

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多