Итеративный углубленный поиск выбранных плохих ходов

Я пишу игру Nine Men's Morris, и пока у меня есть поиск Negascout, который работает просто отлично. Однако я хотел бы добавить итеративное углубление, поэтому я придумал такой код:

public Move GetBestMove(IBoard board, int depth)
{        
    //Search limits (ms
    this.maxTime = 9000; 

    //Set initial window
    int alpha = -INFINITY, beta = INFINITY;
    int val = 0;

    //The move that will be returned
    Move bestMove = null;      

    //Get list of moves for the current board 
    List<Move> moves = board.getMoves();

    //Get the time search has started
    long startTime = System.nanoTime();

    //Iterate through the depths
    for (curDepth = 1; ; )
    {
        maxDepth = curDepth;

        //Reset alpha
        alpha = -INFINITY;

        //Reset the best score position
        int bestPos = -1;

        //Loop through all the moves
        for (int i = 0, n = moves.size(); i < n; i++)
        {
            //Make the move
            board.make(moves.get(i), true);

            //Search deeper
            val = negascout(board, curDepth, alpha, beta, startTime);

            //Undo the move
            board.undo(moves.get(i));

            //Keep best move
            if (val > alpha)
            {
                bestMove = moves.get(i);
                bestPos = i;
            }

            //Score missed aspiration window
            if (val <= alpha || val >= beta)
            {
                alpha = -INFINITY;
                beta = INFINITY;

                //Go to next iteration
                continue;
            }

            //Set new aspiration window
            alpha = val - ASPIRATION_SIZE;
            if (alpha < -INFINITY)
                alpha = -INFINITY;

            beta = val + ASPIRATION_SIZE;
            if (beta > INFINITY)
                beta = INFINITY;
        }

        //Move the best move to the top of the list
        if (bestPos != -1)
        {
            moves.remove(bestPos);
            moves.add(0, bestMove);
        }

        //Time check
        double curTime = (System.nanoTime() - startTime) / 1e6;
        if (curTime >= maxTime ||
            val == board.getMaxScoreValue() ||
            val == -board.getMaxScoreValue())
            break;

        //Increment current depth
        curDepth++;
    }

    //Return the move
    return bestMove;
}

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


person Ivan-Mark Debono    schedule 20.03.2013    source источник
comment
Если он всегда возвращает наихудший ход, вы должны проверить свою ветку выбора if(val > alpha) Разве это не должно быть наоборот?   -  person Thomas Jungblut    schedule 20.03.2013
comment
№ val улучшился по сравнению с альфой, так что на данный момент это лучший ход.   -  person Ivan-Mark Debono    schedule 20.03.2013


Ответы (2)


Поскольку вы используете negascout, ваш первоначальный вызов должен выглядеть так:

val = -negascout(board, curDepth - 1, -beta, -alpha, startTime);

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

person Zong    schedule 30.05.2013

стратегия итеративного углубления:

for (depth = 1;; depth++) {
    val = AlphaBeta(depth, -INFINITY, INFINITY); // or negascout
    if (TimedOut())
        break;
}

выглядит иначе, чем тот, который вы реализовали с помощью GetBestMove. Внутренний цикл (повторение возможных ходов) должен быть частью negascout. Кроме того, кажется, что вы сохраняете порядок ходов только на первом уровне глубины (1-слойный), но чтобы сделать итеративный поиск с углублением действительно быстрым, ему нужен порядок ходов на каждой глубине, которую искали до сих пор. Преимущество итеративного углубления заключается не только в учете времени (заканчивается через x секунд), но также в создании хорошего порядка ходов. А алгоритмы alpha или negascout выигрывают от правильного порядка ходов (сначала попробуйте этот ход, потому что в предыдущем поиске он был лучшим). Распространенным способом реализации порядка ходов является таблица перестановок.

Документы Основная таблица транспонирования и итеративное углубление от Брюса Морленда, который мне очень помог, и я надеюсь, что ссылки помогут и вам!

person Christian Ammer    schedule 20.03.2013