当前位置: 首页 > 知识库问答 >
问题:

实现Alpha-beta剪枝到minimax算法的困难

邴星洲
2023-03-14

我很难让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;
}

}

共有1个答案

何华灿
2023-03-14

你的极小值递归调用和移动世代在逻辑上是正确的,除了你不应该用它直接在里面得出获胜者。你的叶节点评估应该是强大的,这是关键,这在你的代码中似乎是缺乏的。此外,冗长的叶节点函数会使人工智能决策太慢。

下面是递归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参数,这是您在游戏树中找不到的“极限”。此外,我们定义了最大化和最小化玩家,前者是第一个开始玩游戏的玩家。最后,还有一个“深度”,我把它理解