将带有alpha beta修剪的minimax转换为negamax

我写了一个极大极小算法与α+β修剪为游戏跳棋,现在我想使用重写它negamax方法。我期望两者是相等的,因为negamax只是一种写minimax的技术。但是由于某种原因,我的两种算法的行为有所不同。当我在相同的输入上运行它们时,negamax版本似乎可以评估更多状态,因此我认为alpha

beta修剪一定有问题。

下面的代码同时显示了算法(minimaxnegamax函数),并在底部显示了play我从中调用它们的函数。该evaluate函数是我用来评估两种算法中状态的基本启发式方法。

发现错误的任何帮助将不胜枚举。

#include "player.hpp"

#include <algorithm>

#include <limits>

#include <cstdlib>

namespace checkers

{

int evaluatedStates = 0;

int evaluate(const GameState &state)

{

// FIXME: Improve heuristics.

int redScore = 0;

int whiteScore = 0;

int piece = 0;

for (int i = 1; i <= 32; ++i)

{

piece = state.at(i);

if (piece & CELL_RED) {

++redScore;

if (piece & CELL_KING)

redScore += 2; // King bonus.

} else if (piece & CELL_WHITE) {

++whiteScore;

if (piece & CELL_KING)

whiteScore += 2; // King bonus.

}

}

return state.getNextPlayer() == CELL_RED ? whiteScore - redScore : redScore - whiteScore;

}

int minimax(const GameState &state, int depth, int a, int b, bool max)

{

if (depth == 0 || state.isEOG()) {

++evaluatedStates;

return evaluate(state);

}

std::vector<GameState> possibleMoves;

state.findPossibleMoves(possibleMoves);

if (max) {

for (const GameState &move : possibleMoves) {

a = std::max(a, minimax(move, depth - 1, a, b, false));

if (b <= a)

return b; // β cutoff.

}

return a;

} else {

for (const GameState &move : possibleMoves) {

b = std::min(b, minimax(move, depth - 1, a, b, true));

if (b <= a)

return a; // α cutoff.

}

return b;

}

}

int negamax(const GameState &state, int depth, int a, int b)

{

if (depth == 0 || state.isEOG()) {

++evaluatedStates;

return evaluate(state);

}

std::vector<GameState> possibleMoves;

state.findPossibleMoves(possibleMoves);

for (const GameState &move : possibleMoves) {

a = std::max(a, -negamax(move, depth - 1, -b, -a));

if (b <= a)

return b; // β cutoff.

}

return a;

}

GameState Player::play(const GameState &pState, const Deadline &pDue)

{

GameState bestMove(pState, Move());

std::vector<GameState> possibleMoves;

pState.findPossibleMoves(possibleMoves);

int a = -std::numeric_limits<int>::max();

int b = std::numeric_limits<int>::max();

for (const GameState &move : possibleMoves) {

int v = negamax(move, 10, a, b);

//int v = minimax(move, 10, a, b, false);

if (v > a) {

a = v;

bestMove = move;

}

}

std::cerr << "Evaluated states: " << evaluatedStates << std::endl;

return bestMove;

}

/*namespace checkers*/ }

回答:

您的minimax()negamax()功能正确。我认为那state.getNextPlayer()将返回下一个要移动的玩家。这意味着您evaluate()negamax()函数从该玩家的角度返回分数。

但是,minimax()从的角度返回分数max。所以,如果你尝试在取消minimax()在你的play()功能,这将导致一个错误

//int v = negamax(move, 10, a, b);

int v = minimax(move, 10, a, b, false); // assumes perspective of min player

^^^^^

if (v > a) { // assumes perspective of max player

a = v;

bestMove = move;

}

minimax()true参数替换对的调用应该可以解决该问题:

int v = minimax(move, 10, a, b, true); // assumes perspective of max player

以上是 将带有alpha beta修剪的minimax转换为negamax 的全部内容, 来源链接: utcz.com/qa/404515.html

回到顶部