【问题标题】:A* sometimes loops forever when traversing it's path back to the begin nodeA* 在遍历它的路径回到开始节点时有时会永远循环
【发布时间】:2017-06-27 11:47:44
【问题描述】:

我尝试了两种不同的伪代码,来自 WikipediaMIT,最终都给了我相同的结果: 有时,就像在这些屏幕截图上一样,永远遍历循环,因为以某种方式出现了一个链接:

我在 AS3 中包含代码:

{
private function searchPath(e:MouseEvent = null):void 
{
    for (var i:int = 0; i < nodes.length; i ++)
        nodes[i].role = Node.IDLE_NODE;
    
    if (!endNode || !beginNode) return;
    beginNode.role = Node.BEGIN_NODE;
    endNode.role = Node.END_NODE;
    
    openSet.push(beginNode);
    beginNode.g = 0;
    beginNode.f = beginNode.h = heuristicCost(beginNode, endNode);
    addEventListener(Event.ENTER_FRAME, update);
}
    
private function update(e:Event):void 
{
    if (openSet.length)
    {
        // searching for minimal f score node
        var current:Node = openSet[0];
        for (var i:int = 0; i < openSet.length; i ++)
            if (openSet[i].f < current.f)
            {
                current = openSet[i];
            }
        
        current.role = Node.CURRENT_NODE;
        // remove current node from openset
        openSet.splice(openSet.indexOf(current), 1);
        
        
        // walking through neighbours
        for each(var neighbour:Node in current.neighbours)
        {
            if (neighbour == endNode)
            {
                neighbour.parentNode = current;
                highlightPath(neighbour);
                return;
            }
            
            if (current.g + heuristicCost(current, neighbour) >= neighbour.g)
                continue;
            
            neighbour.g = current.g + heuristicCost(current, neighbour);
            neighbour.h = heuristicCost(neighbour, endNode);
            neighbour.f = neighbour.g + neighbour.h;    
            
            // if neighbour is in the closed set or is in the openthen skip it
            if (!(closedSet.indexOf(neighbour) > -1) && (openSet.indexOf(neighbour) < 0))
            {
                openSet.push(neighbour);
                neighbour.parentNode = current;
            }
        }
        // add current node to the closed set
        closedSet.push(current);
    }
    else
    {
        while (closedSet.length) closedSet.pop();
        trace("No solution");
        removeEventListener(Event.ENTER_FRAME, update);
    }
}
private function highlightPath(current:Node):void 
{
    
    var tp:Vector.<Node> = new Vector.<Node>();
    
    tp.push(current);
    
    while (current.parentNode) //this loops forever in situations from screenshots, because there's a link back
    {
        tp.push(current.parentNode);
        current.role = Node.PATH_NODE;
        current = current.parentNode;
    }
    current.role = Node.PATH_NODE;
    
    while (openSet.length) openSet.pop();
    while (closedSet.length) closedSet.pop();
    for (var i:int = 0; i < nodes.length; i ++)
        nodes[i].g = nodes[i].h = nodes[i].f = Infinity;

    removeEventListener(Event.ENTER_FRAME, update);
}
}

不要注意距离!该路径是最佳的,距离较近的节点没有连接(我在屏幕截图上隐藏了连接)。

另外,忘了说截图上的开始节点是黑色的,不是橙色的。

对不起,伙计们,我犯了一个非常愚蠢的错误,我忘记在第一次运行后将节点的 parentNodes 重置为 null。

【问题讨论】:

    标签: actionscript-3 path-finding a-star


    【解决方案1】:

    您应该在设置neighbour.g 时设置neighbour.parentNode = current。现在,您将parentNode 设置为将neighbor 推送到openSet 的第一个节点

    如果您使用正确的数据结构closedSet 的集合;openSet 的优先级队列),您将获得更多更好的性能

    【讨论】:

    • 哦,非常感谢,很抱歉,但我想我犯了最愚蠢的错误。我忘记在第一次运行后将所有 parentNodes 重置为 null。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多