带记忆的Alpha-Beta搜索何时返回截断值?

我已经实现了一个带置换表的Alpha-Beta搜索算法。

我关于在表中存储截断值的想法是否正确?

特别是,当表命中时,我返回截断值的方案是否正确?(同样,存储它们的方式是否正确?)我的实现似乎与这个相冲突,但直觉上我觉得我的方式是正确的。

另外,我的算法从未存储带有at_most标志的条目。我应该在什么时候存储这些条目呢?

以下是展示主要思想的简化代码:

int ab(board *b, int alpha, int beta, int ply) {    evaluation *stored = tt_get(b);    if (entryExists(stored) && stored->depth >= ply) {        if (stored->type == at_least) { // 下界            if (stored->score >= beta) return beta;        } else if (stored->type == at_most) { // 上界            if (stored->score <= alpha) return alpha;        } else { // 精确值            if (stored->score >= beta) return beta; // 遵循严格截断            if (stored->score < alpha) return alpha; // Alpha截断            return stored->score;        }    }       if (ply == 0) return quiesce(b, alpha, beta, ply);    int num_children = 0;    move chosen_move = no_move;    move *moves = board_moves(b, &num_children);    int localbest = NEG_INFINITY;    for (int i = 0; i < num_children; i++) {        apply(b, moves[i]);        int score = -ab(b, -beta, -alpha, ply - 1);        unapply(b, moves[i]);        if (score >= beta) {            tt_put(b, (evaluation){moves[i], score, at_least, ply});            return beta; // 严格截断        }        if (score >= localbest) {            localbest = score;            chosen_move = moves[i];            if (score > alpha) alpha = score;        }    }    tt_put(b, (evaluation){chosen_move, alpha, exact, ply});    return alpha;}

回答:

我的实现似乎与这个相冲突

我认为置换表查找的代码是正确的。它大致相当于维基百科上的代码。

// 使用你的符号/变量名重写的维基百科代码if (entryExists(stored) && stored->depth >= ply){  if (stored->type == at_least)    alpha = max(alpha, stored->score);  else if (stored->type == at_most)    beta = min(beta, stored->score);  else if (stored->type == exact)    return stored->score;  if (alpha >= beta)    return stored->score;}

这相当于(检查if (alpha >= beta)已移动到每个节点类型内部):

if (entryExists(stored) && stored->depth >= ply){  if (stored->type == at_least)  {    alpha = max(alpha, stored->score);    if (alpha >= beta)  return stored->score;  }  else if (stored->type == at_most)  {    beta = min(beta, stored->score);    if (alpha >= beta)  return stored->score;  }  else if (stored->type == exact)    return stored->score;}

并且这可以改为:

if (entryExists(stored) && stored->depth >= ply){  if (stored->type == at_least)  {    // if (max(alpha, stored->score) >= beta) ...    if (stored->score >= beta)  return stored->score;  }  else if (stored->type == at_most)  {    // if (min(beta, stored->score) <= alpha) ...    if (stored->score <= alpha)  return stored->score;  }  else if (stored->type == exact)    return stored->score;}

剩下的区别是维基百科使用了软失败优化,而你的代码是经典的Alpha-Beta剪枝(硬失败)。软失败是一个小的改进,但不会改变算法的关键点。


我的算法从未存储带有at_most标志的条目。我应该在什么时候存储这些条目呢?

你存储exact / at_most节点类型的方式存在一个错误。这里你假设节点总是exact类型:

tt_put(b, (evaluation){chosen_move, alpha, exact, ply});

实际上它可能是at_most节点:

if (alpha <= initial_alpha){  // 这里我们没有最佳移动。  tt_put(b, (evaluation){no_move, initial_alpha, at_most, ply});}else   tt_put(b, (evaluation){chosen_move, alpha, exact, ply});

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注