我很难让Alpha-beta修剪正常工作。我有一个函数Minimax算法,我试着去适应,但没有用。我在维基百科上用了这个例子
目前,该算法似乎在大多数情况下都按预期运行,但不管怎样,它都会选择第一个测试节点。
这可能是因为缺乏理解,但我已经花了数小时阅读了这篇文章。让我困惑的是,在零和博弈中,算法如何知道当达到深度极限时哪个节点是最佳选择;在哪一点上,我们还不能确定哪位球员会从这样的举动中受益最大,是吗?
不管怎样,我的朋友。cpp在下面。无论是我原来的极小极大函数和任何帮助将不胜感激!
AIMove ComputerInputComponent::FindBestMove() {
const Graph<HexNode>* graph = HexgameCore::GetInstance().GetGraph();
std::vector<AIMove> possibleMoves;
FindPossibleMoves(*graph, possibleMoves);
AIMove bestMove = AIMove();
int alpha = INT_MIN;
int beta = INT_MAX;
int depth = 6;
Node* currentNode;
for (const AIMove &move : possibleMoves) {
std::cout << move << std::endl;
graph->SetNodeOwner(move.x, move.y, (NodeOwner)aiPlayer);
int v = MiniMaxAlphaBeta(*graph, depth, alpha, beta, true);
graph->SetNodeOwner(move.x, move.y, NodeOwner::None);
if (v > alpha) {
alpha = v;
bestMove.x = move.x;
bestMove.y = move.y;
}
}
return bestMove;
}
template<typename T>
int ComputerInputComponent::Minimax Alphabeta(常数图
std::vector<AIMove> possibleMoves;
FindPossibleMoves(graph, possibleMoves);
if (lastTestedNode != nullptr) {
Pathfinder pathFinder;
bool pathFound = pathFinder.SearchForPath(lastTestedNode, graph.GetMaxX(), graph.GetMaxY());
if (pathFound) {
//std::cout << "pathfound-" << std::endl;
if ((int)lastTestedNode->GetOwner() == aiPlayer) {
std::cout << "cpuWin-" << std::endl;
return 10;
}
else if ((int)lastTestedNode->GetOwner() == humanPlayer) {
std::cout << "playerWin-" << std::endl;
return -10;
}
}
else {
if (depth == 0) {
//std::cout << "NoPath-" << std::endl;
return 0;
}
}
}
if (isMaximiser) {// Max
int v = -INT_MAX;
for (const AIMove &move : possibleMoves) {
graph.SetNodeOwner(move.x, move.y, (NodeOwner)aiPlayer);
graph.FindNode(move.x, move.y, lastTestedNode);
v = std::max(alpha, MiniMaxAlphaBeta(graph, depth - 1, alpha, beta, false));
alpha = std::max(alpha, v);
graph.SetNodeOwner(move.x, move.y, NodeOwner::None);
if (beta <= alpha)
break;
}
return v;
}
else if (!isMaximiser){ // Min
//std::cout << "Human possiblMoves size = " << possibleMoves.size() << std::endl;
int v = INT_MAX;
for (const AIMove &move : possibleMoves) {
graph.SetNodeOwner(move.x, move.y, (NodeOwner)humanPlayer);
v = std::min(beta, MiniMaxAlphaBeta(graph, depth - 1, alpha, beta, true));
beta = std::min(beta, v);
graph.SetNodeOwner(move.x, move.y, NodeOwner::None);
if (beta <= alpha)
break;
}
return v;
}
}
你的极小值递归调用和移动世代在逻辑上是正确的,除了你不应该用它直接在里面得出获胜者。你的叶节点评估应该是强大的,这是关键,这在你的代码中似乎是缺乏的。此外,冗长的叶节点函数会使人工智能决策太慢。
下面是递归MiniMax函数的伪代码。假设parent_graph是评估最佳移动之前的状态,leaf_graph是当前离开节点的状态。你必须在极小极大树中找到相对(不要与绝对)最好的分支。
if (depth == 0) {
return EvaluateLeafNode(isMaximizing,parent_graph,leaf_graph);
}
评估LeafNode函数可以这样读:
int EvaluateLeafNode(bool isMaximizing,Graph& parent_graph,Graph& leaf_graph)
{
int score = 0;
int w = find_relative_white_deads(parent_graph,leaf_graph);
int b = find_relative_black_deads(parent_graph,leaf_graph);
if(isMaximizing)
score += b;
else
score += w;
return score;
}
我正在尝试为一个游戏创建一个AI播放器,使用带有alpha-beta修剪的minimax算法。我在正确地执行它时遇到了一些困难。我有两个功能要使用,一个用于评估给定玩家(返回一些分数)getBoardScore的当前棋盘状态,另一个用于返回每个可能移动(从给定玩家的给定棋盘状态)GetPossibleBoard创建的所有可能棋盘状态。 我的AI通过最初调用alphaBeta,将其传递到当前的板状态
在我的方法newminimax49中,我有一个minimax算法,它利用了本文中建议给我的记忆和其他一般性改进。该方法使用一个简单的启发式电路板评估函数。我的问题基本上是关于alpha-beta修剪,即我的minimax方法是否使用alpha-beta修剪。据我所知,我相信这是真的,然而,我用来实现它的东西似乎太简单了,不可能是真的。此外,其他人建议我使用alpha-beta剪枝,正如我所说的,我
我在写国际象棋的最小化算法。 对于不带alpha-beta修剪的minimax和带alpha-beta修剪的minimax,我得到了不同的最终结果值。 下面是我的伪代码。有人能帮我吗? 极小极大() αβ() 董事会代表董事会。对于每一次移动,我都在传递的董事会对象的副本上移动,然后将这个临时董事会传递给进一步的调用。 evaluateBoard(董事会b)接收董事会并根据给定董事会情景计算分数。
我试图在我的极小值中添加阿尔法贝塔修剪,但我不明白我哪里出错了。 目前,我正在经历5000次迭代,根据一个朋友的说法,我应该经历大约16000次迭代。当选择第一个位置时,它返回-1(一个损失),而它应该能够在这一点上肯定返回0(一个平局),因为它应该能够从一个空的棋盘中抽签,但是我看不到我哪里出错了,因为我跟着我的代码走似乎没问题 奇怪的是,如果我在我的检查中切换返回α和β(以实现返回0),计算机
我想为一个类似跳棋的游戏实现一个人工智能 我写了以下方法: -方法 这将返回所有按重量排序的有效移动的列表,其中重量是根据移动的类型和位置计算的 -方法 将移动应用于棋盘,如果有棋子被杀则返回1 -方法 以恢复板的先前状态。 这是一个零和游戏,所以人工智能应该最大化玩家颜色的棋子,最小化对手的棋子。 为此,最好的方法似乎是使用最小-最大和α-β修剪。这有以下伪码 但我还没有明白如何适应我的问题。有
我目前正在从事我的第一个C项目,并选择使用基于Minimax的AI编写一个Connect Four(又名Score 4),更具体地说是基于Alpha-Beta修剪方法。 到目前为止,我了解到AB修剪包含在一个递归算法中,该算法考虑了一个alpha和一个beta参数,这是您在游戏树中找不到的“极限”。此外,我们定义了最大化和最小化玩家,前者是第一个开始玩游戏的玩家。最后,还有一个“深度”,我把它理解