【问题标题】:Minimax algorithm doesn't return best moveMinimax 算法不返回最佳移动
【发布时间】:2012-03-01 06:46:29
【问题描述】:

我正在编写一个使用带有 alpha-beta 修剪的 minimax 的 Othello 引擎。 它工作正常,但我发现以下问题:

当算法发现一个位置丢失时,它按预期返回-INFINITY,但在 在这种情况下,我无法跟踪“最佳”移动...该位置已经丢失,但无论如何它应该返回一个有效的移动(最好是一个存活时间更长的移动,就像好的国际象棋引擎一样)。

代码如下:

private float minimax(OthelloBoard board, OthelloMove best, float alpha, float beta, int depth)
{             
    OthelloMove garbage = new OthelloMove();             
    int currentPlayer = board.getCurrentPlayer();

    if (board.checkEnd())
    {                        
        int bd = board.countDiscs(OthelloBoard.BLACK);
        int wd = board.countDiscs(OthelloBoard.WHITE);

        if ((bd > wd) && currentPlayer == OthelloBoard.BLACK)                
            return INFINITY;
        else if ((bd < wd) && currentPlayer == OthelloBoard.BLACK)                           
            return -INFINITY;            
        else if ((bd > wd) && currentPlayer == OthelloBoard.WHITE)                            
            return -INFINITY;            
        else if ((bd < wd) && currentPlayer == OthelloBoard.WHITE)                            
            return INFINITY;            
        else                             
            return 0.0f;            
    }
    //search until the end? (true during end game phase)
    if (!solveTillEnd )
    {
        if (depth == maxDepth)
            return OthelloHeuristics.eval(currentPlayer, board);
    }

    ArrayList<OthelloMove> moves = board.getAllMoves(currentPlayer);             

    for (OthelloMove mv : moves)
    {                        
        board.makeMove(mv);            
        float score = - minimax(board, garbage, -beta,  -alpha, depth + 1);           
        board.undoMove(mv);             

        if(score > alpha)
        {  
            //Set Best move here
            alpha = score;                
            best.setFlipSquares(mv.getFlipSquares());
            best.setIdx(mv.getIdx());        
            best.setPlayer(mv.getPlayer());                              
        }

        if (alpha >= beta)
            break;                

    }                
    return alpha;
}

我称之为:

AI ai = new AI(board, maxDepth, solveTillEnd);

//create empty (invalid) move to hold best move
OthelloMove bestMove = new OthelloMove();
ai.bestFound = bestMove;
ai.minimax(board, bestMove, -INFINITY, INFINITY, 0);

//dipatch a Thread
 new Thread(ai).start();
//wait for thread to finish

OthelloMove best = ai.bestFound();

当搜索一个丢失的位置(例如,想象它在 10 步之后丢失)时,上面的最佳变量等于作为参数传递的空无效移动...为什么??

感谢您的帮助!

【问题讨论】:

  • 请阅读faq和How to Ask,并提出更具体的问题。另外,您的问题不完整;您没有显示类AI 的定义,这对问题非常关键
  • 问题是概念性的,而不是代码问题。我提供的代码足以解决我认为的问题。但无论如何,谢谢,我会阅读这篇文章以了解更多信息。

标签: java algorithm search minimax


【解决方案1】:

您的问题是您使用 -INFINITY 和 +INFINITY 作为赢/输分数。您的赢/输分数应该高于/低于任何其他位置评估分数,但不等于您的无穷大值。这将保证即使在无可救药的位置上也会选择移动。

【讨论】:

  • 你刚刚解决了问题,谢谢!现在,当达到丢失位置时,我返回 INFINITY/10 或 -INFINITY/10。如果我理解得很好,我必须返回一个介于 -INF 和 +INF 之间的值,对吧?
  • 正确,只要只有赢或输的位置才能返回这些值。
  • 您还应该尝试让函数根据您赢或输的数量返回一个值,这样如果您赢了 64 件,它应该返回一个更大的值,如果您赢了 50 件。这样,您的算法不仅会搜索胜利,还会搜索最佳胜利。所有获胜条件的值都应大于非获胜条件的任何值。
【解决方案2】:

自从我实现 minimax 以来已经有很长时间了,所以我可能错了,但在我看来,如果您遇到赢或输的举动,您的代码不会更新最佳变量(这发生在 (board.方法顶部的 checkEnd()) 语句)。

另外,如果您希望您的算法尽可能多地获胜,或者如果无法获胜,则尽可能少地输掉,我建议您更新您的 eval 函数。在获胜的情况下,它应该返回一个较大的值(大于任何非获胜情况),您使用该值赢得的越多。在输的情况下,它应该返回一个很大的负值(小于任何非输的情况),你输的越多,值越小。

在我看来(没有尝试过)如果您以这种方式更新您的 eval 函数并完全跳过检查 if (board.checkEnd()),您的算法应该可以正常工作(除非它有其他问题)。祝你好运!

【讨论】:

    【解决方案3】:

    如果您可以检测到一个位置是真正赢了还是输了,那么这意味着您正在解决残局。在这种情况下,您的评估函数应该返回游戏的最终得分(例如,64 表示全胜,31 表示险胜),因为这可以准确计算,与您将在中期评估的估计不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-18
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      • 2022-11-06
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多