当前位置: 首页 > 知识库问答 >
问题:

我的Negamax算法有阿尔法-贝塔修剪的问题吗?

方韬
2023-03-14

我正在尝试建立一个国际象棋AI。我的带有 alpha-beta 修剪的 negamax 函数 (ABP) 比使用 ABP 的单独最小和最大函数运行得慢得多(约 8 倍),尽管返回的移动是相等的.

我的棋盘评估函数总是返回一个关于红色玩家的值,即红色玩家越高越好。仅对于 Negamax,当返回深度 0 时,黑色玩家的此值乘以 -1。

我的Netamax函数:

int alphaBeta(Board board, int depth, int alpha, int beta) {
    if (depth <= 0 || board.isGameOver()) { // game over == checkmate/stalemate
        int color = board.getCurrPlayer().getAlliance().isRed() ? 1 : -1;
        return BoardEvaluator.evaluate(board, depth) * color;
    }

    int bestVal = Integer.MIN_VALUE + 1;
    for (Move move : MoveSorter.simpleSort(board.getCurrPlayer().getLegalMoves())) {
        MoveTransition transition = board.getCurrPlayer().makeMove(move);
        if (transition.getMoveStatus().isAllowed()) { // allowed == legal && non-suicidal
            int val = -alphaBeta(transition.getNextBoard(), depth - 1, -beta, -alpha);
            if (val >= beta) {
                return val; // fail-soft
            }
            if (val > bestVal) {
                bestVal = val;
                alpha = Math.max(alpha, val);
            }
        }
    }        

    return bestVal;
}

根调用:

-alphaBeta(transition.getNextBoard(), searchDepth - 1,
                        Integer.MIN_VALUE + 1, Integer.MAX_VALUE); // +1 to avoid overflow when negating

我的最小和最大函数:

int min(Board board, int depth, int alpha, int beta) {
    if (depth <= 0 || board.isGameOver()) {
        return BoardEvaluator.evaluate(board, depth);
    }

    int minValue = Integer.MAX_VALUE;
    for (Move move : MoveSorter.simpleSort(board.getCurrPlayer().getLegalMoves())) {
        MoveTransition transition = board.getCurrPlayer().makeMove(move);
        if (transition.getMoveStatus().isAllowed()) {
            minValue = Math.min(minValue, max(transition.getNextBoard(), depth - 1, alpha, beta));
            beta = Math.min(beta, minValue);
            if (alpha >= beta) break; // cutoff
        }
    }

    return minValue; 
}

int max(Board board, int depth, int alpha, int beta) {
    if (depth <= 0 || board.isGameOver()) {
        return BoardEvaluator.evaluate(board, depth);   
    }

    int maxValue = Integer.MIN_VALUE;
    for (Move move : MoveSorter.simpleSort(board.getCurrPlayer().getLegalMoves())) {
        MoveTransition transition = board.getCurrPlayer().makeMove(move);
        if (transition.getMoveStatus().isAllowed()) {
            maxValue = Math.max(maxValue, min(transition.getNextBoard(), depth - 1, alpha, beta));
            alpha = Math.max(alpha, maxValue);
            if (alpha >= beta) break; // cutoff
        }
    }

    return maxValue;
}

根分别调用红色和黑色玩家:

min(transition.getNextBoard(), searchDepth - 1, Integer.MIN_VALUE, Integer.MAX_VALUE);
max(transition.getNextBoard(), searchDepth - 1, Integer.MIN_VALUE, Integer.MAX_VALUE);

我猜 Negamax 函数中的截止有一个错误,尽管我从这里遵循了伪代码。任何帮助不胜感激,谢谢!

编辑:alphaBeta()的调用量大约是min()和max()的总和的6倍,而beta截止的数量只有2倍左右。

共有1个答案

茅桐
2023-03-14

解决。我也应该发布根调用的完整代码 - 没有意识到我没有为 beta 传递新值。Alpha/beta 实际上是在根方法中更新为单独的最小-最大值。

更新了Negamax的根方法:

Move bestMove = null;
int bestVal = Integer.MIN_VALUE + 1;

for (Move move : MoveSorter.simpleSort(currBoard.getCurrPlayer().getLegalMoves())) {
    MoveTransition transition = currBoard.getCurrPlayer().makeMove(move);
    if (transition.getMoveStatus().isAllowed()) {
        int val = -alphaBeta(transition.getNextBoard(), searchDepth - 1, Integer.MIN_VALUE + 1, -bestVal);
        if (val > bestVal) {
            bestVal = val;
            bestMove = move;
        }
    }
}

return bestMove;

很抱歉我的问题中缺乏信息——我没想到会有这个错误。

 类似资料:
  • 我最近实现了极小极大和阿尔法贝塔修剪算法,我100%确定(自动分级器)我正确地实现了它们。但是当我执行我的程序时,它们的行为不同。我99%确定极小极大和阿尔法贝塔的结束状态应该是相同的。我说得对吗?它们在实现结果的路径上会有所不同吗?因为我们忽略了min将选择的一些值,而max不会选择这些值,反之亦然。

  • 我正在为2048年开发一个人工智能,并且即将应用极大极小算法。 然而,2048的搜索树实际上就像一棵没有民角色的期望极小树。我想知道如果我没有民角色,我怎么能在实践中应用α-β剪枝? 如果我不应该在这个场景中应用alpha-beta修剪,我怎么能减少无用的搜索分支? 任何想法将不胜感激。谢谢你。

  • 我已经实现了迭代深化的alpha beta搜索,并且我已经阅读了一些技术来进一步优化算法,首先搜索从以前的深度搜索中出现的最佳移动。 据我所知,我可以只将先前深度搜索的主要变化存储在动态长度列表中吗?例如,假设我使用PV[1,0,2,3]搜索到深度4,这意味着在深度1选择移动数1,在深度2选择移动数0,在深度3选择移动数2,等等...,然后对于深度5搜索,该算法将首先从先前的深度PV搜索节点的子节

  • 15min超短面 ①介绍项目 ②卷积相对全连接最大的优势 ③常用损失函数 ④常用正则化 ⑤知不知道目标检测 ⑥数据预处理方法 ⑦用过哪些神经网络 ⑧用什么深度学习框架 ⑨有过实际pytorch部署经验吗 回去等通知,还会再联系(也不知道是不是真的),感觉自己有关CV方面的没答好,毕竟我也不是搞CV的,不过看他们的JD也不是强制要求CV方向咯,不晓得后续如何

  • 1、个人信息再确认,哪个学校毕业的,考研还是保研,以后打算读博还是工作etc 2、介绍你的研究方向 3、介绍下你的研究内容,另外发了论文没 4、常用的数据预处理方法有哪些 5、l1正则和l2正则哪个收敛更快?为什么 6、l1正则和l2正则哪个抑制过拟合效果更好?为什么 7、用过哪些网络 8、transformer了解吗? 9、l1、l2在深层还是浅层抑制过拟合的效果好? 10、dropout用过吗

  • ''处理命令时发生未知的服务器端错误。原始错误:执行adbExec时出错。原始错误:“命令”D:\program\android sdk\platform tools\adb。exe-P 5037-s f8cb3e08安装-g E:\appium\resources\app\node_modules\appium\node_modules\io。阿皮姆。设置\apks\settings\u apk