C++ C++;Negamaxα-β截止错误?
我一直在用negamax玩连接四。我注意到的一点是,如果我加上alpha-beta,它有时会给出“错误”的结果,比如在做一个失败的动作时,我认为它不应该与我搜索的深度相匹配。如果我删除alpha-beta,它将按预期方式播放。阿尔法-贝塔能切断一些实际可行的分支吗(特别是在深度有限的情况下)?以下是代码,以防万一: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) { //
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(rootState, depth, −extremePoints, +extremePoints, color)
alpha
/beta
是可能的最低和最高值
如果对alpha
/beta
(例如)使用不同的初始值,并且真实分数在初始窗口之外,则需要重新搜索
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。