1

Я пытаюсь реализовать минимаксный алгоритм для небольшой шахматной игры. Возможно, мое предположение ошибочно, и это не то, что нужно пытаться. Это?Облицовочные проблемы производительности, реализующие минимакс для шахматной игры

Программа работает, но есть большая проблема с производительностью:

  • Depth = 0, 1 или 2 результат немедленно.
  • Глубина = 3 Результат занимает 15 секунд.
  • Глубина = 4 - пока нет результатов.

Вот моя реализация:

private Move findBestMove(Chessboard chessboard, int depth, 
     boolean maximizingPlayer) { 
    if (depth == 0) { 
     return new Move(chessboard.calculateHeuristicValue()); 
    } else { 
     Move bestMove; 
     if (maximizingPlayer) { 
      bestMove = new Move(Integer.MIN_VALUE); 
      for (Move possibleMove : findAllPossibleMoves(chessboard, 
        !(maximizingPlayer^whiteTurn))) { 
       Move move = findBestMove(
         possibleMove.getResultChessboard(), depth - 1, 
         !maximizingPlayer); 
       if (move.getValue() > bestMove.getValue()) { 
        possibleMove.setValue(move.getValue()); 
        bestMove = possibleMove; 
       } 
      } 
     } else { 
      bestMove = new Move(Integer.MAX_VALUE); 
      for (Move possibleMove : findAllPossibleMoves(chessboard, 
        !(maximizingPlayer^whiteTurn))) { 
       Move move = findBestMove(
         possibleMove.getResultChessboard(), depth - 1, 
         !maximizingPlayer); 
       if (move.getValue() < bestMove.getValue()) { 
        possibleMove.setValue(move.getValue()); 
        bestMove = possibleMove; 
       } 
      } 
     } 
     return bestMove; 
    } 
} 

Может быть, есть ошибка в реализации алгоритма или при проектировании объектов или при их использовании. Я не могу на нее наложить. Поэтому я хочу быть уверенным, что нет основной проблемы, которую я пропущу, прежде чем пытаться оптимизировать код или настроить конфигурацию памяти в программе.

Примечание: нет опыта с профилированием памяти.

+1

минимакс экспоненциальный. чтобы уменьшить количество изученных ветвей, вы можете использовать обрезку алфавита – njzk2

ответ

2

В шахматах есть 20 возможностей совершить первый ход (16 пешками и 4 рыцарями).

Для простоты предположим, что это также верно для следующих ходов.

  • Для глубины 1 MinMax учитывает только 20 ходов.
  • Для глубины 2, MinMax считает 20 ходов и 20 ответов на этот ход, 400 возможных ходов, никаких проблем.
  • Для глубины 3 MinMax считает 20^3 = 8.000 возможных ходов. Уже 15 секунд на вашем компьютере.
  • Для глубины 4 MinMax считает 20^4 = 160 000 возможных ходов. Это займет примерно 20 раз дольше, чем предыдущий ...

Просто пространство поиска становится слишком большим - оно растет экспоненциально с размером ввода (глубины). Сложность времени - O (глубина 20 см).

Но нам не нужно искать через все пространство, чтобы найти действительно хорошие ходы.

Alpha-beta pruning - популярная оптимизация для MinMax.

Если этого недостаточно, я бы рассмотрел возможность переключения на совершенно другой алгоритм - например, Monte Carlo Tree Search (с UCT).

Перемещение баз данных также может помочь - вместо вычисления первых ходов вы уже подготовили (предварительно вычисленные) гамбиты.

Знаменитый Deep Blue, который избил Каспарова в 1997 году, использовал их, вы можете проверить, что еще он использовал here.

Смежные вопросы