【问题标题】:Cannot figure out what's wrong with my A* Algorithm无法弄清楚我的 A* 算法出了什么问题
【发布时间】:2015-01-04 21:04:49
【问题描述】:

我目前正在我的 2D 横向滚动条中实现 A* 寻路算法,但我遇到了一些困难。

认为我正确地实现了它,但显然不是,因为它不起作用。

我使用优先级队列来提高效率,并遵循此处讨论的算法:

http://www.codeproject.com/Articles/5758/Path-finding-in-C

但是,我没有使用他们的优先级队列,因为许多 cmets 指出它存在一些问题。相反,我使用以下优先级队列:

https://bitbucket.org/BlueRaja/high-speed-priority-queue-for-c/src

这是我的功能,然后我将讨论这个问题:

List<Waypoint> FindPathTo(Waypoint Goal)
{
    TileMath goalMath = TileMath.GetTileMath((int)Goal.x, (int)Goal.y);

    Waypoint startPt = new Waypoint((Vector2)this.transform.position);
    HeapPriorityQueue<Waypoint> OpenList = new HeapPriorityQueue<Waypoint>(MAX_NODES);
    HeapPriorityQueue<Waypoint> ClosedList = new HeapPriorityQueue<Waypoint>(MAX_NODES);

    List<Waypoint> Solution = new List<Waypoint>();

    OpenList.Enqueue(startPt, openPriority);
    openPriority--;

    print(Goal.GetPoint()); //testing
    print(OpenList.Count); //testing

    while (OpenList.Count > 0)
    {
        Waypoint CurrNode = OpenList.Dequeue();

        TileMath currMath = TileMath.GetTileMath((int)CurrNode.x, (int)CurrNode.y);

        if (currMath.GetXY() == goalMath.GetXY() && currMath.GetBlockID() == goalMath.GetBlockID()) // checks if the current node is the goal
        {
            while (CurrNode != null)
            {
                Solution.Insert(0, CurrNode);

                CurrNode = CurrNode.prev;

            }
            break;
        }

        List<Waypoint> successors = CurrNode.GetSuccessors();

        print(successors.Count);

        foreach (Waypoint w in successors)
        {
            Waypoint OpenWp = null;
            Waypoint ClosedWp = null;
            if(OpenList.Contains(w))
            {

                IEnumerator<Waypoint> ie = OpenList.GetEnumerator();

                while((int)ie.Current.x != (int)w.x && (int)ie.Current.y != (int)w.y && ie.Current != null)
                {
                    ie.MoveNext();
                }

                if (ie.Current == null)
                    print("IE ERROR. CHECK CONTAINS IN OPENLIST.");
                else
                    OpenWp = ie.Current;



                if (OpenWp != null && w.totalCost > OpenWp.totalCost)
                    continue;



            }
            if(ClosedList.Contains(w))
            {

                IEnumerator<Waypoint> ie = ClosedList.GetEnumerator();

                while ((int)ie.Current.x != (int)w.x && (int)ie.Current.y != (int)w.y && ie.Current != null)
                {
                    ie.MoveNext();
                }

                if (ie.Current == null)
                    print("IE ERROR. CHECK CONTAINS IN CLOSEDLIST.");
                else
                    ClosedWp = ie.Current;



                if (ClosedWp != null && w.totalCost > ClosedWp.totalCost)
                    continue;
            }

            if (OpenWp != null)
                OpenList.Remove(OpenWp);
            if (ClosedWp != null)
                ClosedList.Remove(ClosedWp);

            OpenList.Enqueue(w, openPriority);
            openPriority--;
            ClosedList.Enqueue(w, closedPriority);
            closedPriority--;


        }
    }

    return Solution;

}

基本上,我有返回航点列表的方法(非常简单的类,如果您有兴趣,这里是它的粘贴箱:http://pastebin.com/Sch5vRY3),但是在我的函数中,返回时列表的计数为 0,因此(错误地)表示没有到达该点的路径。

我已经完成了通常的调试,但是 A* 让我有点困惑,所以如果有人能帮助我解决常见的陷阱,我将不胜感激。

我绝对是人工智能和寻路的新手,所以如果您有任何其他杂项指针,我会全力以赴!

谢谢。

【问题讨论】:

  • 你把这个方法放在哪里了?还有一些变量我们看不到它们分配在哪里
  • 制作一个测试用例。然后制作一个仍然失败的较小的测试用例。尝试找到产生错误输出的最小/最简单的输入。
  • 这篇文章向我们展示了一些不完整的代码,并且不知道输入数据。你不能指望一个严肃的答案。
  • @HenkHolterman 是的,也许代码很大,不管大小,这个问题我们无法给出确切的答案
  • @HenkHolterman 我需要添加什么才能完成?我一直在尝试大量测试,但是由于我对 A* 缺乏了解,这让它变得很困难,因为我什至不确定我是否正确理解了算法。

标签: c# artificial-intelligence path-finding a-star


【解决方案1】:

好吧,我不会告诉确切的代码,但我会告诉你什么是 A* 算法以及在你的情况下它是什么:
在 A* 中,我们定义了状态的两个函数:成本和启发式,成本的意思是“从当前状态转移到另一个状态的成本是多少”,在你的情况下,它应该是当前点之间的路径距离以及我会尝试的重点。
启发式的意思是“我离目标有多远”,在你的情况下,从我的位置到目标的距离可能会很大。
编写完这两个函数后,您编写了一个函数,我们称它为“f”,将两者相加。
A* 算法实际上是一个贪婪的回溯算法,在其中你尝试最少的“f”。

【讨论】:

  • 您认为我上面使用的链接 (codeproject.com/Articles/5758/Path-finding-in-C) 是构建它的好资源吗?还是有更简单的资源?我正在讨论取消该功能并更有条理地重做它。我已经有了启发式方法和存储成本的能力,但我很难理解许多资源解释 A* 的方式。
  • @Jestus 您的资源是具体的,它一般不能解释 A*。
  • @Jestus “但我很难理解许多资源解释 A* 的方式”可能是因为它们专门针对一个问题解释它,你需要一个能够概括地解释它的问题,我从大学就知道今年学了,用在一个项目中。
  • 您能推荐任何特定的在线资源吗?
  • @Jestus 抱歉,但我指望大学,这对我来说已经足够了,我不知道任何在线资源:)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-28
  • 1970-01-01
  • 2015-12-31
  • 2018-05-09
  • 1970-01-01
  • 1970-01-01
  • 2021-05-18
相关资源
最近更新 更多