难以对minimax算法实施Alpha-beta修剪

时间:2018-03-05 23:37:21

标签: artificial-intelligence minimax alpha-beta-pruning

我在使Alpha-beta修剪工作正常时遇到了一些困难。 我有一个功能性的Minimax算法,我试图适应,但无济于事。我在Wikipedia

上使用了这个例子

目前,该算法似乎在大多数情况下按预期运行,但随后它选择了第一个被测试的节点。

这可能是由于缺乏了解,但我已经花了几个小时阅读。令我感到困惑的是,当算法在零和游戏中达到其深度限制时,该算法应该如何知道哪个节点是最佳选择;在这一点上,不能确定哪个玩家会从这样的行动中受益最多,是吗?

无论如何,我的.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 :: MiniMaxAlphaBeta(const Graph&amp; graph,int depth,int alpha,int beta,bool isMaximiser){

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 个答案:

答案 0 :(得分:0)

您的minimax递归调用和移动代数在逻辑上是正确的,除非您不应该使用它直接在内部结束获胜者。你的叶节点评估应该很强,这是关键,你的代码似乎缺乏。此外,详细的叶节点函数将使AI决策变得太慢。

这是递归MiniMax函数的伪代码.Say parent_graph是评估最佳移动前的状态,leaf_graph是当前离开节点状态。你必须在极小极大树中找到相对(不要与绝对混合)最佳分支。

if (depth == 0) {           
        return EvaluateLeafNode(isMaximizing,parent_graph,leaf_graph);
    }

EvaluateLeafNode函数可以这样读:

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;
}