Самая быстрая кроссплатформенная реализация A *? - PullRequest
14 голосов
/ 21 января 2010

С таким количеством доступных реализаций, что является самым быстрым (наименее загруженным процессором, наименьшим двоичным), кроссплатформенным (Linux, Mac, Windows, iPhone) A * реализация для C ++ с использованием небольшой сетки?

Реализация

Google возвращает:

Кто-нибудь еще?

Колесо

Вопрос в том виде, в котором он задан, касается повторного использования (подключения к игре), а не переизобретения (по крайней мере, до тех пор, пока производительность не станет проблемой). Может оказаться, что реализация Dijkstra (или универсальный алгоритм поиска пути) лучше подходит, или что самые быстрые реализации не достаточно быстрые. Я ценю предложения альтернативных алгоритмов, однако вопрос не в том, «Должен ли я бросить свой собственный A *?»

Ответы [ 5 ]

6 голосов
/ 21 января 2010

Посмотрите на другие алгоритмы поиска пути (например, Breath-First, Depth-First, Minimax, Negmax и т. Д.) И взвесьте позитивы и негативы для вашего сценария.

Повышение также имеет A-star реализацию . Попробуйте выполнить эти инструкции для создания надстройки на iPhone, но она может не сработать для вас: это не «полный порт» надстройки и может произойти ошибка.

Следующее от Алгоритмы в двух словах (Java, а не C ++, но, возможно, вы захотите его портировать):

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 );
}
6 голосов
/ 21 января 2010

Если у вас есть конкретные границы, с которыми вы можете работать, обычно лучше самим написать алгоритм. В частности, ваше небольшое пространство состояний поддается оптимизации, которая тратит память заранее, чтобы сократить время процессора, и тот факт, что вы используете сетку, а не произвольное пространство состояний, позволяет вам выполнять такие вещи, как оптимизация генерации узла-преемника, или уметь обрабатывать все частичные пути, заканчивающиеся на одном и том же квадрате сетки, как эквивалентные (чего не может и не допускает обычный поиск A *).

(PS. OpenSteer, набор функций управления, не имеет ничего общего с A *, который является алгоритмом поиска, за исключением того, что вы можете условно использовать одно, другое или оба для обхода пробела. замена другого в самых разумных обстоятельствах.)

5 голосов
/ 21 января 2010

У меня есть два общих совета:

  • Если ваш домен ограничен сеткой, возможно, вы найдете лучшие результаты, выполнив поиск "поиск пути", а не в более общем виде A *.
  • Если ваш домен не строго ищет пути вдоль поверхности, вы можете получить больше преимуществ от своих усилий, если потратите свое время на улучшение эвристики, а не на оптимизацию самого алгоритма.
5 голосов
/ 21 января 2010

Я предлагаю вам реализовать алгоритм самостоятельно. Следуйте псевдокоду по адресу: A * Алгоритм поиска , и он должен быть прямым. «Openset» должен быть реализован как мини-куча, что тоже тривиально; или вы можете использовать priority_queue из STL.

2 голосов
/ 02 февраля 2010

Существует общая реализация C ++ A * на http://www.ceng.metu.edu.tr/~cuneyt/codes.html. Похоже, что это все кроссплатформенный стандарт C ++.

...