首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优化A-Star算法

优化A-Star算法
EN

Stack Overflow用户
提问于 2010-08-09 03:11:13
回答 5查看 6.1K关注 0票数 6

我已经根据维基百科在here上的实现实现了A*算法,但是在移动设备上运行它太慢了。虽然它在台式电脑上运行得很好,但我不得不等待无尽的时间才能完成这个功能。我能做些什么来优化算法吗?

下面是实际的代码

代码语言:javascript
复制
public DriveRoute findroute(routenode from, routenode to)
        {
            Dictionary<int, routenode> openlist = new Dictionary<int, routenode>();
            openlist.Add(from.nodeid, from);
            Dictionary<int, routenode> closedlist = new Dictionary<int, routenode>();
            Dictionary<int, double> gscores = new Dictionary<int, double>();
            gscores.Add(from.nodeid, 0);
            Dictionary<int, double> hscores = new Dictionary<int, double>();
            hscores.Add(from.nodeid, distanceForRouting(from.latlon, to.latlon));
            Dictionary<int, double> fscores = new Dictionary<int, double>();
            fscores.Add(from.nodeid, gscores[from.nodeid] + hscores[from.nodeid]);
            Dictionary<int, routenode> came_from = new Dictionary<int, routenode>();
            while (openlist.Values.Count > 0)
            {
                routenode x = getLowestFscore(openlist, fscores);
                if (x.latlon.Equals(to.latlon))
                {
                    return rebuildPathWay(came_from, to);
                }
                openlist.Remove(x.nodeid);
                closedlist.Add(x.nodeid, x);
                foreach (routearc arc in x.outgoingarcs)
                {
                    if (closedlist.Keys.Contains(arc.endnode))
                        continue;
                    double tentative_g_score = gscores[x.nodeid] + arc.time;
                    bool tentative_is_better = false;
                    if (!openlist.Keys.Contains(arc.endnode))
                    {
                        openlist.Add(arc.endnode, map.routenodes[arc.endnode]);
                        tentative_is_better = true;
                    }
                    else if (tentative_g_score < gscores[arc.endnode])
                    {
                        tentative_is_better = true;
                    }
                    if (tentative_is_better)
                    {
                        if (came_from.ContainsKey(arc.endnode))
                            came_from[arc.endnode] = x;
                        else
                            came_from.Add(arc.endnode, x);
                        gscores[arc.endnode] = tentative_g_score;
                        hscores[arc.endnode] = distanceForRouting(arc.endlatlon, to.latlon);
                        fscores[arc.endnode] = gscores[arc.endnode] + hscores[arc.endnode];
                    }
                }
            }
            return null;
        }
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-08-09 03:27:54

在看不到完整代码的情况下,很难给出任何提示,但我可以给出一些提示:

您在字典上所做的主要操作是查找成本最低的内容。字典后面的数据结构应该针对此操作进行优化。典型的数据结构应该是堆(不是与new/delete malloc/free相关的内容,而是数据结构:http://en.wikipedia.org/wiki/Heap_%28data_structure%29 )

你会发现这种数据结构的子类型,比如斐波那契堆等等。值得一试。在没有实现A*的情况下,我也会尝试一下splay-tree (在wiki上搜索一下就会找到结果)。

第二:您是否在算法运行时插入和删除节点?如果是这样的话,请确保您自己构建了一个预先分配的节点池,并使用它,而不是调用new/delete或malloc/free。内存分配可能非常慢。

票数 5
EN

Stack Overflow用户

发布于 2010-08-09 03:24:49

您应该在优先级队列中缓存每个节点的分数。这样,您只需在每次需要新节点时从优先级队列中弹出第一个节点,而不必调用getLowestFscore。在实现PriorityQueue时,只需使用SortedDictionary<int, List<routenode>>。使用SetDefault (有关示例,请参阅here )使您的工作变得更容易。

此外,由于您在移动设备上遇到了更多问题,这可能是内存问题。在这种情况下,您可能想要考虑使用有界BeamSearch -它不会每次都提供最好的结果,但它应该运行得更快。

票数 1
EN

Stack Overflow用户

发布于 2010-08-09 03:27:04

你能并行化for循环吗?您是否正在使用具有多核的特定移动设备?如果是这样,请查看Tasks.Parallel.For(....)或者Foreach。

此外,请考虑缓存任何可以缓存的信息。

你为什么使用A*而不是Djikstra的算法?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3435674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档