Альфа-бета порядок ходов - PullRequest
12 голосов
/ 01 апреля 2012

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

Есть предложения, как реализовать одно из этих улучшений в этом алгоритме?

 public double alphaBetaPruning(Board board, int depth, double alpha, double beta, int player) {
    if (depth == 0) {
        return board.evaluateBoard();
    }

    Collection<Move> children = board.generatePossibleMoves(player);
    if (player == 0) {
        for (Move move : children) {
            Board tempBoard = new Board(board);
            tempBoard.makeMove(move);
            int nextPlayer = next(player);
            double result = alphaBetaPruning(tempBoard, depth - 1, alpha,beta,nextPlayer);
            if ((result > alpha)) {
                alpha = result;
                if (depth == this.origDepth) {
                    this.bestMove = move;
                }
            }
            if (alpha >= beta) {
                break;
            }
        }
        return alpha;
    } else {
        for (Move move : children) {
            Board tempBoard = new Board(board);
            tempBoard.makeMove(move);
            int nextPlayer = next(player);
            double result = alphaBetaPruning(tempBoard, depth - 1, alpha,beta,nextPlayer);
            if ((result < beta)) {
                beta = result;
                if (depth == this.origDepth) {
                    this.bestMove = move;
                }
            }
            if (beta <= alpha) {
                break;
            }
        }
        return beta;
    }
}

public int next(int player) {
    if (player == 0) {
        return 4;
    } else {
        return 0;
    }
}

Ответы [ 2 ]

16 голосов
/ 01 апреля 2012
  • Переупорядочение узлов с мелким поиском тривиально: вычислите эвристическое значение для каждого дочернего элемента состояния перед их рекурсивной проверкой .Затем сортируйте значения этих состояний [по убыванию для максимальной вершины и по возрастанию для минимальной вершины] и рекурсивно вызывайте алгоритм в отсортированном списке.Идея состоит в том, что если состояние хорошо на небольшой глубине, то оно более вероятно также хорошо и на глубоком состоянии, и если это правда, вы получите больше сокращений.

    Сортировка должна быть сделана до этого [в обоих пунктах if и else]

    for (Move move : children) {

  • сохранение ходов также тривиально - многие состояния вычисляются дважды, когда вы заканчиваете вычисление любого состояния, сохраняйте его [с глубиной вычисления!это неправда!] в HashMap.Первое, что вы делаете, когда начинаете вычисление с вершины, - проверяете, вычислено ли оно уже - и, если это так, возвращает кэшированное значение.Идея заключается в том, что многие состояния достижимы по разным путям, поэтому таким образом вы можете исключить избыточные вычисления.

    Изменения должны быть выполнены как в первой строке метода [что-то вроде if (cache.contains((new State(board,depth,player)) return cache.get(new State(board,depth,player))][извините за отсутствие элегантности и эффективности - просто объясняя идею здесь].
    Вы также должны добавить cache.put(...) перед каждым return оператором.

1 голос
/ 16 октября 2015

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

Это не всегда быстрее, потому что это не гарантирует сокращения, если факт в худшем случае не будет вообще сокращать и искать абсолютно то же самое дерево как минимаксное и будет медленнее из-за значений a / bведение бухгалтерского учета.В лучшем случае (максимальное сокращение) это позволяет искать дерево в 2 раза глубже одновременно.Для случайного дерева он может искать в 4/3 раза глубже за то же время.

Порядок перемещения может быть реализован несколькими способами:

  1. у вас есть эксперт по домену, который даетВы предлагаете, какие ходы лучше.Например, в шахматном промоушене пешки, захват ценных фигур с более низкой ценой - это в среднем хорошие ходы.В шашках лучше убить больше шашек за ход, чем меньше шашек, и лучше создать ферзя.Таким образом, ваша функция генерации ходов возвращает лучшие ходы до
  2. , и вы получаете эвристическую оценку того, насколько хорош этот шаг, от оценки позиции на 1-м уровне глубины (ваш мелкий поиск / итеративное углубление).Вы рассчитали оценку на глубине n-1, отсортировали ходы, а затем оценили на глубине n.

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

...