【问题标题】:C++ Negamax alpha-beta wrong cutoff?C ++ Negamax alpha-beta错误截止?
【发布时间】:2016-10-21 12:14:48
【问题描述】:

我一直在使用 negamax 玩四连接。我注意到的是,如果我添加 alpha-beta,它有时会给出“错误”的结果,因为在做出失败的举动时,我认为它不应该以我正在搜索的深度进行。如果我删除 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;
}

【问题讨论】:

    标签: c++ artificial-intelligence alpha-beta-pruning negamax


    【解决方案1】:

    alpha-beta 能否切断一些实际可行的分支(尤其是在深度有限的情况下)?

    Alpha-Beta 算法返回与 Minimax 相同的结果(在根节点和播放线的评估)但(通常)在更快的时间内修剪掉不可能影响最终决策的分支(您可以阅读 H. Fuller 在 Analysis of the alpha-beta pruning algorithm by Samuel 中的证明 - 1973)。

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

    fail-soft 的噱头也不会改变这种情况。

    当然,浅层搜索可以选择不好的移动,但对于 Minimax 也是如此。

    所以它一定是一个实现错误。

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

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

       negamax(rootState, depth, −extremePoints, +extremePoints, color)
      

      alpha / beta 是可能的最低和最高值。

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

    2. 您如何收集/存储/管理/传播主要变体的动作(缺少相关代码)。 PV-tables 等技术与bestValue 的更改相关联。如果这是问题所在,您应该在该位置上获得相同的分数(相对于 Minimax),但最佳移动不同。

    【讨论】:

    • 非常感谢,我不再怀疑有限的深度和 alpha beta。最后结果是一个实现错误(我在正确的多线程中搞砸了)。
    【解决方案2】:

    问题是如何在根节点初始化alphabeta。我遇到了类似的错误,因为我将它们设置为 std::numeric_limits&lt;int&gt;::min()std::numeric_limits&lt;int&gt;::max()最低int 价值!!因为最小值int 的数学否定超出了“int”数据类型的范围(完整范围是:-2147483648 vs 2147483647) 我们不能在int 类型中表示正...648,所以它回落到负最小值。

    但是,如果您将 alpha 初始化为稍高的值(例如 std::numeric_limits&lt;int&gt;::min() + 1),则情况并非如此。

    【讨论】:

    • 我知道这篇文章已经有好几年了,但是谢谢,这是我的问题。在 c++ 中,INT32_MIN 否定仍然是负数,所以我不得不使用 INT32_MIN + 1。
    • 好多年了,谢谢!
    猜你喜欢
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多