【问题标题】:Looking for speedups for A* search寻找 A* 搜索的加速
【发布时间】:2012-03-07 22:38:37
【问题描述】:

我在 C# 中有以下工作 A* 代码:

static bool AStar(
    IGraphNode start,
    Func<IGraphNode, bool> check,
    out List<IGraphNode> path)
{
    // Closed list. Hashset because O(1).
    var closed =
        new HashSet<IGraphNode>();
    // Binary heap which accepts multiple equivalent items.
    var frontier =
        new MultiHeap<IGraphNode>(
            (a, b) =>
            { return Math.Sign(a.TotalDistance - b.TotalDistance); }
            );
    // Some way to know how many multiple equivalent items there are.
    var references =
        new Dictionary<IGraphNode, int>();
    // Some way to know which parent a graph node has.
    var parents =
        new Dictionary<IGraphNode, IGraphNode>();

    // One new graph node in the frontier,
    frontier.Insert(start);
    // Count the reference.
    references[start] = 1;

    IGraphNode current = start;

    do
    {

        do
        {
            frontier.Get(out current);
            // If it's in the closed list or
            // there's other instances of it in the frontier,
            // and there's still nodes left in the frontier,
            // then that's not the best node.
        } while (
            (closed.Contains(current) ||
            (--references[current]) > 0) &&
            frontier.Count > 0
            );

        // If we have run out of options,
        if (closed.Contains(current) && frontier.Count == 0)
        {
            // then there's no path.
            path = null;
            return false;
        }


        closed.Add(current);
        foreach (var edge in current.Edges)
        {
            // If there's a chance of a better path
            // to this node,
            if (!closed.Contains(edge.End))
            {
                int count;
                // If the frontier doesn't contain this node,
                if (!references.TryGetValue(edge.End, out count) ||
                    count == 0)
                {
                    // Initialize it and insert it.
                    edge.End.PathDistance =
                        current.PathDistance + edge.Distance;
                    edge.End.EstimatedDistance = CalcDistance(edge.End);
                    parents[edge.End] = current;
                    frontier.Insert(edge.End);
                    references[edge.End] = 1;
                }
                else
                {
                    // If this path is better than the existing path,
                    if (current.PathDistance + edge.Distance <
                        edge.End.PathDistance)
                    {
                        // Use this path.
                        edge.End.PathDistance = current.PathDistance +
                            edge.Distance;
                        parents[edge.End] = current;
                        frontier.Insert(edge.End);
                        // Keeping track of multiples equivalent items.
                        ++references[edge.End];
                    }
                }
            }
        }
    } while (!check(current) && frontier.Count > 0);

    if (check(current))
    {
        path = new List<IGraphNode>();
        path.Add(current);
        while (current.PathDistance != 0)
        {
            current = parents[current];
            path.Add(current);
        }
        path.Reverse();
        return true;
    }

    // Yep, no path.
    path = null;
    return false;
}

如何让它更快?没有代码示例,请;这是我给自己设定的挑战。

编辑:澄清一下,我正在寻找一般适用于 A* 的任何建议、建议、链接等。代码只是一个例子。我没有要求提供代码示例,因为它们使实现所描述的技术变得太容易了。

谢谢。

【问题讨论】:

    标签: a-star


    【解决方案1】:

    你看过this pagethis page 了吗?他们有很多有用的优化技巧以及一些关于 A* 的一般信息。

    【讨论】:

    • 我读过第一本;不确定第二个。似乎很熟悉。谢谢。
    • 没问题,希望你能找到你要找的东西。
    • 不用担心;这只是一个提升我技能的副业。 :)
    【解决方案2】:

    更改为对堆结构使用 Random Meldable Queue。由于您想要一个编程挑战,我不会向您展示我是如何将递归 Meld 方法更改为不递归的。这就是从这种结构中获得速度的诀窍。 Gambin 的论文“Randomized Meldable Priority Queues”中的更多信息(在网上搜索)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-08
      • 1970-01-01
      • 2017-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多