C++ C++;Negamaxα-β截止错误?

C++ C++;Negamaxα-β截止错误?,c++,artificial-intelligence,alpha-beta-pruning,negamax,C++,Artificial Intelligence,Alpha Beta Pruning,Negamax,我一直在用negamax玩连接四。我注意到的一点是,如果我加上alpha-beta,它有时会给出“错误”的结果,比如在做一个失败的动作时,我认为它不应该与我搜索的深度相匹配。如果我删除alpha-beta,它将按预期方式播放。阿尔法-贝塔能切断一些实际可行的分支吗(特别是在深度有限的情况下)?以下是代码,以防万一: int negamax(const GameState& state, int depth, int alpha, int beta, int color) { //

我一直在用negamax玩连接四。我注意到的一点是,如果我加上alpha-beta,它有时会给出“错误”的结果,比如在做一个失败的动作时,我认为它不应该与我搜索的深度相匹配。如果我删除alpha-beta,它将按预期方式播放。阿尔法-贝塔能切断一些实际可行的分支吗(特别是在深度有限的情况下)?以下是代码,以防万一:

int negamax(const GameState& state, int depth, int alpha, int beta, int color)
{
    //depth end reached? or we actually hit a win/lose condition?
    if (depth == 0 || state.points != 0)
    {

        return color*state.points;
    }

    //get successors and optimize the ordering/trim maybe too
    std::vector<GameState> childStates;
    state.generate_successors(childStates);
    state.order_successors(childStates);

    //no possible moves - then it's a terminal state
    if (childStates.empty())
    {
        return color*state.points;
    }
    int bestValue = -extremePoints;
    int v;
    for (GameState& child : childStates)
    {
        v = -negamax(child, depth - 1, -beta, -alpha, -color);
        bestValue = std::max(bestValue, v);
        alpha = std::max(alpha, v);
        if (alpha >= beta)
            break;
    }
    return bestValue;
}
int-negamax(常量游戏状态和状态、int-depth、int-alpha、int-beta、int-color)
{
//达到深度终点?或者我们实际上达到了一个赢/输的条件?
如果(深度==0 | | state.points!=0)
{
返回颜色*state.points;
}
//获得继任者并优化订购/修剪,可能也是如此
std::向量子状态;
州。生成继承人(子州);
州。继承人(子女州);
//没有可能的移动-那么它是一个终端状态
if(childStates.empty())
{
返回颜色*state.points;
}
int-bestValue=-extremePoints;
INTV;
用于(游戏状态和子:子状态)
{
v=-negamax(子级,深度-1,-beta,-alpha,-color);
最佳值=标准::最大值(最佳值,v);
α=标准::最大值(α,v);
如果(α>=β)
打破
}
返回最佳值;
}
阿尔法-贝塔能切断一些实际可行的分支吗(特别是在深度有限的情况下)

Alpha-Beta算法返回与Minimax相同的结果(在根节点和播放线处的求值),但(通常)更快地修剪掉不可能影响最终决策的分支(您可以阅读H.Fuller-1973中的一个证明)

您正在使用Negamax Alpha-Beta修剪,但它只是简化算法实现的一个变体

而且噱头也不会改变这种情况

当然,在浅层搜索可能会发现错误的移动,但对于极大极小值也是如此

所以这一定是一个实现错误

显示的代码对我来说似乎是正确的。您应该检查:

  • 在根节点调用negamax的方式。应该是这样的:

     negamax(rootState, depth, −extremePoints, +extremePoints, color)
    
    alpha
    /
    beta
    是可能的最低和最高值

    如果对
    alpha
    /
    beta
    (例如)使用不同的初始值,并且真实分数在初始窗口之外,则需要重新搜索

  • 如何收集/存储/管理/传播主体变体的移动(缺少相关代码)。PV表等技术与
    bestValue
    的更改相关联。如果这是一个问题,你应该得到相同的位置分数(关于极小值),但不同的最佳移动


  • 问题是如何在根节点上初始化
    alpha
    beta
    。我有一个类似的错误,因为我将它们相应地设置为
    std::numeric_limits::min()
    std::numeric_limits::max()
    ,并将
    alpha
    参数传递给另一个递归调用
    negamax(…-a_beta,-a_alpha…)
    我通过添加一个仍然产生最小
    int
    值的减号运算符来否定最小
    int
    值!!因为最小
    int
    的数学求反超出了“int”数据类型的范围(完整范围是:-2147483648与2147483647),所以我们不能在
    int
    类型中表示正…648,所以它返回到负最小值


    但是,如果将
    alpha
    初始化为稍高一点的值(例如
    std::numeric\u limits::min()+1
    ),则情况并非如此。

    非常感谢,我不再怀疑有限的深度和alpha beta。最后,它被证明是一个实现错误(我在多线程处理方面弄错了)。我知道这篇文章已经有好几年了,但谢谢你,这是我的问题。在C++中,32位否定仍然是否定的,所以我必须使用It3xMIN + 1。