Alpha-Beta 搜索截断了我的主要变体
Alpha-Beta search truncating my principal variation
我实现了 alpha-beta 搜索,将其结果添加到换位 table。然后,我从转置 table.
中提取主要变化
这似乎适用于浅层分析。然而,当我要求在 7 层深度进行分析时,我得到了这个:
7 [+1.00] 1.b1c3 a7a6 2.g1f3 a6a5 3.a6a5
最后,重复一个动作。由于修剪,这最后一步被放置在 table 中,但它甚至不是白方的合法举动。很明显,打印不到7层。
这是对我的 alpha-beta 搜索代码的误解吗?
int ab_max(board *b, int alpha, int beta, int ply) {
if (ply == 0) return evaluate(b);
int num_children;
move chosen_move = no_move;
move *moves = board_moves(b, &num_children);
assert(num_children > 0);
for (int i = 0; i < num_children; i++) {
apply(b, moves[i]);
int score = ab_min(b, alpha, beta, ply - 1);
if (score >= beta) {
tt_put(b, (evaluation){moves[i], score, at_least, ply});
unapply(b, moves[i]);
free(moves);
return beta; // fail-hard
}
if (score > alpha) {
alpha = score;
chosen_move = moves[i];
}
unapply(b, moves[i]);
}
tt_put(b, (evaluation){chosen_move, alpha, exact, ply});
free(moves);
return alpha;
}
int ab_min(board *b, int alpha, int beta, int ply) {
if (ply == 0) return evaluate(b);
int num_children;
move chosen_move = no_move;
move *moves = board_moves(b, &num_children);
assert(num_children > 0);
for (int i = 0; i < num_children; i++) {
apply(b, moves[i]);
int score = ab_max(b, alpha, beta, ply - 1);
if (score <= alpha) {
tt_put(b, (evaluation){moves[i], score, at_most, ply});
unapply(b, moves[i]);
free(moves);
return alpha; // fail-hard
}
if (score < beta) {
beta = score;
chosen_move = moves[i];
}
unapply(b, moves[i]);
}
tt_put(b, (evaluation){chosen_move, beta, exact, ply});
free(moves);
return beta;
}
这是我的评估打印功能中有趣的部分:
do {
if (!b->black_to_move) printf("%d.", moveno++);
char move[6];
printf("%s ", move_to_string(eval->best, move));
apply(b, eval->best);
eval = tt_get(b);
} while (eval != NULL && depth-- > 0);
我的主要变化中的任何一步都不应该被修剪,对吗?
我正在回答我自己的问题,以节省未来国际象棋作者几个小时的悲伤。
有一个小错误,当发生截止时,我太晚取消了移动。
然而,这里描述了更有趣的问题:Chess: Extracting the principal variation from the transposition table
我实现了 alpha-beta 搜索,将其结果添加到换位 table。然后,我从转置 table.
中提取主要变化这似乎适用于浅层分析。然而,当我要求在 7 层深度进行分析时,我得到了这个:
7 [+1.00] 1.b1c3 a7a6 2.g1f3 a6a5 3.a6a5
最后,重复一个动作。由于修剪,这最后一步被放置在 table 中,但它甚至不是白方的合法举动。很明显,打印不到7层。
这是对我的 alpha-beta 搜索代码的误解吗?
int ab_max(board *b, int alpha, int beta, int ply) {
if (ply == 0) return evaluate(b);
int num_children;
move chosen_move = no_move;
move *moves = board_moves(b, &num_children);
assert(num_children > 0);
for (int i = 0; i < num_children; i++) {
apply(b, moves[i]);
int score = ab_min(b, alpha, beta, ply - 1);
if (score >= beta) {
tt_put(b, (evaluation){moves[i], score, at_least, ply});
unapply(b, moves[i]);
free(moves);
return beta; // fail-hard
}
if (score > alpha) {
alpha = score;
chosen_move = moves[i];
}
unapply(b, moves[i]);
}
tt_put(b, (evaluation){chosen_move, alpha, exact, ply});
free(moves);
return alpha;
}
int ab_min(board *b, int alpha, int beta, int ply) {
if (ply == 0) return evaluate(b);
int num_children;
move chosen_move = no_move;
move *moves = board_moves(b, &num_children);
assert(num_children > 0);
for (int i = 0; i < num_children; i++) {
apply(b, moves[i]);
int score = ab_max(b, alpha, beta, ply - 1);
if (score <= alpha) {
tt_put(b, (evaluation){moves[i], score, at_most, ply});
unapply(b, moves[i]);
free(moves);
return alpha; // fail-hard
}
if (score < beta) {
beta = score;
chosen_move = moves[i];
}
unapply(b, moves[i]);
}
tt_put(b, (evaluation){chosen_move, beta, exact, ply});
free(moves);
return beta;
}
这是我的评估打印功能中有趣的部分:
do {
if (!b->black_to_move) printf("%d.", moveno++);
char move[6];
printf("%s ", move_to_string(eval->best, move));
apply(b, eval->best);
eval = tt_get(b);
} while (eval != NULL && depth-- > 0);
我的主要变化中的任何一步都不应该被修剪,对吗?
我正在回答我自己的问题,以节省未来国际象棋作者几个小时的悲伤。
有一个小错误,当发生截止时,我太晚取消了移动。
然而,这里描述了更有趣的问题:Chess: Extracting the principal variation from the transposition table