C ++ Negamax alpha-beta错误截止?

时间:2016-06-20 09:37:51

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

我一直在使用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;
}

2 个答案:

答案 0 :(得分:2)

  

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表这样的技术与bestValue的变化相关联。如果这是问题,你应该得到相同的位置分数(相对于Minimax),但是不同的最佳动作。

答案 1 :(得分:0)

问题是如何在根节点初始化alpha和beta。我有一个类似的错误,因为我将它们设置为std :: numeric_limits :: min()和std :: numeric_limits :: max(),并在将alpha参数传递给另一个递归调用negamax(... -a_beta, - a_alpha ...)我通过添加一个减号运算符来否定最小int值,因为最小int值的数学否定超出了int的范围(-214748364 8 vs 214748364 <强> 7 )。

但是,如果将alpha初始化为不同的值(例如std :: numeric_limits :: min()+ 1),则不是这种情况。