简体   繁体   English

如何加快我的A *寻路功能?

[英]How can I speed up my A* Pathfinding?

My path-finding works fine when moving with no obstacles or when moving from the top to the side of an obstacle but when it needs to find it's way from the top to the bottom of an obstacle it is too slow. 当没有障碍物移动或从障碍物的顶部移动到障碍物的侧面时,我的寻路效果很好,但是当它需要找到从障碍物的顶部到底部的路径时,速度太慢。

I'm fairly sure it's the way I am sorting each loop or looping though the closed set but I'm not sure how to avoid this as SortedLists are not available on windows phone 7 我相当确定这是我对每个循环进行排序或通过封闭集进行循环的方式,但是我不确定如何避免这种情况,因为Windows Phone 7上没有SortedLists

//This Vivid Destination means it doesn't have to find the exact location 
//which is helpful as it is continuous environment  
Rectangle vividDestination = new Rectangle((int)character.destination.X - 10, (int)character.destination.Y - 10, 20, 20);

while (!vividDestination.Contains(Maths.vectorToPoint(OpenNodes[0].position)))
{
    Node Current = OpenNodes[0];
    OpenNodes.RemoveAt(0);
    ClosedNodes.Add(Current);
    Current.calculateNeightbours();

    foreach (Node neighbour in Current.neighbours)
    {
        neighbour.parents = Current.parents + 1;
        //The cost of the node is the amount of parent nodes + the distance to destination
        neighbour.cost = calculateCost(neighbour.position, character.destination, neighbour.parents);

        for (int i = 0; i < OpenNodes.Count; i++)
        {
            //Round Vector rounds the floats in the Vector to the nearest integer
            if (Maths.roundVector(OpenNodes[i].position) == Maths.roundVector(neighbour.position) && OpenNodes[i].parents < neighbour.parents)
            {
                break;
            }
            else
            {
                OpenNodes.RemoveAt(i);
                OpenNodes.Add(neighbour);
                i--;
                break;
            }
        }

        bool closedNode = false;
        for (int i = 0; i < ClosedNodes.Count; i++)
        {
            if (Maths.roundVector(ClosedNodes[i].position) == Maths.roundVector(neighbour.position))
            {
                closedNode = true;
                break;
            }
        }

        if (!closedNode)
        {
            OpenNodes.Add(neighbour);
        }
    }

    OpenNodes = OpenNodes.OrderBy(item => item.cost).ToList();
}

What you are doing is horribly inefficient. 您正在做的事情效率低下。 The sorting of the list takes n*log(n) time, and you sort the list once for each vertex in the graph. 列表的排序花费n * log(n)的时间,并且您对图形中的每个顶点都对列表进行了一次排序。 This result in an algorithm that takes V^2*log(V) time, where V is the number of vertices. 这导致算法花费V ^ 2 * log(V)时间,其中V是顶点数。 If you simply keep an unsorted list then you can extract the minimum in linear time by looping over all the items and keeping count of the lowest one so far. 如果仅保留未排序的列表,则可以通过遍历所有项目并保持到目前为止的最低计数来提取线性时间中的最小值。 In this case, the time becomes V^2. 在这种情况下,时间变为V ^ 2。 This is only a tiny improvement. 这只是微小的改进。 Of course, if you use a proper priority queue (like one based on a Binary Heap ) then the algorithm will run much, much faster still since then operations only cost log(n). 当然,如果您使用适当的优先级队列(例如基于Binary Heap的队列),则该算法将运行得多,更快得多,因为这样操作仅花费log(n)。 Coding your own binary heap is not too difficult and it's something I would strongly recommend you do if the platform doesn't support one natively. 编写自己的二进制堆不是很困难,如果平台本机不支持,我强烈建议您这样做。 In this case insertion and finding the minimum only take log(n) time, resulting in a E log V time (where E is the number of edges, which in a planar graph is proportional to V). 在这种情况下,插入和找到最小值仅花费log(n)时间,从而导致E log V时间(其中E是边的数量,在平面图中与V成正比)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM