最快的跨平台A*实施? 使用这么多的实现,什么是执行速度最快(最小CPU密集型,最小二进制),跨平台(Linux,MAC,Windows,iPhone)A*实现使用小网格的C++?< /P>

最快的跨平台A*实施? 使用这么多的实现,什么是执行速度最快(最小CPU密集型,最小二进制),跨平台(Linux,MAC,Windows,iPhone)A*实现使用小网格的C++?< /P>,c++,iphone,algorithm,a-star,C++,Iphone,Algorithm,A Star,实施 谷歌返回: (该网站上的大多数链接都已失效。) (据说比Heyes Jones慢。) (通用C++代码) (对于游戏来说很有趣,而不是*) 还有其他的吗 车轮 正如所问的,这个问题是关于重用(插入游戏),而不是重新发明(至少在性能被证明是一个问题之前)。结果可能是Dijkstra实现(或通用寻路算法)更适合,或者最快的实现不够快。我很欣赏其他算法的建议,但问题不是“我应该自己申请A*?” 我建议您自己实现该算法。遵循:处的伪代码,它应该是直接的。“openset”应该作为一

实施

谷歌返回:

  • (该网站上的大多数链接都已失效。)
  • (据说比Heyes Jones慢。)
  • (通用C++代码)
  • (对于游戏来说很有趣,而不是*)
还有其他的吗

车轮

正如所问的,这个问题是关于重用(插入游戏),而不是重新发明(至少在性能被证明是一个问题之前)。结果可能是Dijkstra实现(或通用寻路算法)更适合,或者最快的实现不够快。我很欣赏其他算法的建议,但问题不是“我应该自己申请A*?”


    • 我建议您自己实现该算法。遵循:处的伪代码,它应该是直接的。“openset”应该作为一个最小堆来实现,这也是很简单的;或者您可以使用STL中的优先级队列。

      当您可以使用特定的边界时,通常最好自己编写算法。特别是,您的小状态空间有助于优化,这些优化会提前花费内存以减少CPU时间,而且您使用的是网格而不是任意状态空间,这一事实使您能够优化后续节点生成,或者能够将终止于同一网格正方形上的所有部分路径视为等效路径(普通a*搜索不会也不能假设)


      (注:OpenSteer是一个转向行为的集合,它与a*无关,a*是一种搜索算法,除了你可以在概念上使用一个、另一个或两者来遍历一个空间。在最合理的情况下,一个不能替代另一个。)

      我有两条建议:

      • 如果您的域被限制为网格,那么您可能会通过搜索“寻路”而不是更通用的a*,找到更好的结果
      • 如果您的域没有严格地沿着曲面搜索路径,那么如果您花时间改进启发式而不是尝试优化算法本身,您的工作可能会获得更多好处

      查看其他路径查找算法(如呼吸优先、深度优先、极小值最大、负最大值等),并权衡您的场景的利弊

      另外,试着在iPhone上构建Boost,但它可能不适合你:它不是Boost的“完整端口”,可能会出错

      以下是(java,不是C++,但也许你想把它移植):

      公共解决方案搜索(INode初始,INode目标){
      //从初始状态开始
      INodeSet open=StateStorageFactory.create(StateStorageFactory.TREE);
      INode copy=initial.copy();
      评分(复印件);
      打开。插入(副本);
      //使用哈希表存储我们已经访问过的状态。
      INodeSet closed=StateStorageFactory.create(StateStorageFactory.HASH);
      而(!open.isEmpty()){
      //删除具有最小求值函数的节点并标记为关闭。
      INode n=open.remove();
      闭合。插入(n);
      //如果达到目标状态,则返回。
      如果(n.equals(goal)){返回新解(initial,n);}
      //计算后续移动并更新打开/关闭列表。
      depthttransition=(depthttransition)n.storedData();
      int深度=1;
      如果(trans!=null){depth=trans.depth+1;}
      DoubleLinkedList moves=n.validMoves();
      for(Iterator it=moves.Iterator();it.hasNext();){
      IMove move=it.next();
      //进行移动并为新板状态打分。
      INode继任者=n.copy();
      移动、执行(继任者);
      //记录解决方案跟踪和计算的上一步
      //评估功能,以查看我们是否改进了
      //已经关闭的州
      继承者.storedData(新的深度转换(移动,n,深度));
      scoringFunction.score(后继);
      //如果已经访问过,请查看我们是否与较低的
      //成本。如果没有,继续;否则,退出关闭
      //和过程
      INode pass=closed.contains(后继);
      如果(过去!=null){
      如果(继任者.score()>=过去的.score()){
      继续;
      }
      //我们以更低的成本再次访问。
      关闭。移除(过去);
      }
      //放在露天。
      打开。插入(继任者);
      }
      }
      //没有解决办法。
      返回新的解决方案(初始、目标、错误);
      }
      

      有一个通用的C++ A*实现。它看起来像是跨平台的标准C++。< /P>同意。A*本身不是很复杂,并且经常可以被优化到特定的情况。因为STL不允许改变已经插入的元素的优先级,所以不能从STL使用<代码> PrimyIyQueLe2/Standard >。(强制堆重建效率极低)。对于像我这样的凡人来说,实现一个高效的a*,它不会花费大部分时间遍历列表,并保持内存消耗合理(例如,避免在关闭的列表中存储完整的节点)“一点也不平凡。@kuroineko实际上你可以使用

      优先级\u队列
      ,因为当你更改优先级时,你不需要删除旧节点。你只需在开放集中再次插入优先级更高的节点,它将首先被拾取并放入封闭集中(然后是“旧”节点)开放集中的节点稍后将被丢弃,因为它已经在封闭集中了)我投票支持第二个项目符号。第一个项目符号有点混乱,因为我认为“寻路”可能比“a*”更通用A*可以用于任何类型的搜索问题,路径查找是一个定义良好的领域:从曲面的一个点导航到另一个点。+1表示第二个点。Th
      public Solution search( INode initial, INode goal ) {
        // Start from the initial state
        INodeSet open = StateStorageFactory.create( StateStorageFactory.TREE );
        INode copy = initial.copy();
        scoringFunction.score( copy );
        open.insert( copy );
      
        // Use Hashtable to store states we have already visited.
        INodeSet closed = StateStorageFactory.create( StateStorageFactory. HASH );
        while( !open.isEmpty() ) {
          // Remove node with smallest evaluation function and mark closed.
          INode n = open.remove();
      
          closed.insert( n );
      
          // Return if goal state reached.
          if( n.equals( goal ) ) { return new Solution( initial, n ); }
      
          // Compute successor moves and update OPEN/CLOSED lists.
          DepthTransition trans = (DepthTransition)n.storedData();
          int depth = 1;
      
          if( trans ! = null ) { depth = trans.depth + 1; }
      
          DoubleLinkedList<IMove> moves = n.validMoves();
      
          for( Iterator<IMove> it = moves.iterator(); it.hasNext(); ) {
            IMove move = it.next();
      
            // Make move and score the new board state.
            INode successor = n.copy();
            move.execute( successor );
      
            // Record previous move for solution trace and compute
            // evaluation function to see if we have improved upon
            // a state already closed
            successor.storedData( new DepthTransition( move, n, depth ) );
            scoringFunction.score( successor );
      
            // If already visited, see if we are revisiting with lower
            // cost. If not, just continue; otherwise, pull out of closed
            // and process
            INode past = closed.contains( successor );
      
            if( past ! = null ) {
              if( successor.score() >= past.score() ) {
                continue;
              }
      
              // we revisit with our lower cost.
              closed.remove( past );
            }
      
            // place into open.
            open.insert( successor );
          }
        }
      
        // No solution.
        return new Solution( initial, goal, false );
      }