迭代加深搜索选择了不好的动作

时间:2013-03-20 09:42:44

标签: search artificial-intelligence minimax

我正在写一个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;
}

我也使用了一个愿望窗口。然而,搜索返回最糟糕的举动!我认为问题在于重新/设置搜索窗口。搜索窗口应该移动到外部循环吗?

2 个答案:

答案 0 :(得分:1)

由于你使用的是negascout,你的初始调用应该是

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

与内部节点相比,您的根调用完全相反,因此这就解释了为什么它会返回最糟糕的移动。

答案 1 :(得分:0)

iterative deepening strategy

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

与您使用GetBestMove实施的内容不同。内循环(迭代可能的移动)应该是negascout的一部分。此外,您似乎只在第一深度级别(1层)存储移动顺序,但为了使迭代加深搜索非常快,它需要在目前为止搜索的每个深度处的移动排序。迭代加深不仅具有将时间考虑在内的优点(在x秒后完成),而且还具有产生良好移动顺序的优点。并且alphabeta或negascout算法受益于良好的移动排序(首先尝试此移动,因为在先前的搜索中它是最好的)。实现移动排序的常用方法是transposition table

来自Bruce Moreland的文件The Main Transposition TableIterative Deepening对我非常有帮助,我希望链接也可以帮到你!