在国际象棋游戏中实现极小极大算法时遇到性能问题

我正在尝试为一个小型国际象棋游戏实现极小极大算法。也许我的前提是错误的,这不是应该尝试的事情。真的是这样吗?

程序可以运行,但存在严重的性能问题:

  • 深度为0、1或2时,结果立即返回。
  • 深度为3时,结果需要15秒。
  • 深度为4时,尚未得到结果。

这是我的实现代码:

private Move findBestMove(Chessboard chessboard, int depth,        boolean maximizingPlayer) {    if (depth == 0) {        return new Move(chessboard.calculateHeuristicValue());    } else {        Move bestMove;        if (maximizingPlayer) {            bestMove = new Move(Integer.MIN_VALUE);            for (Move possibleMove : findAllPossibleMoves(chessboard,                    !(maximizingPlayer ^ whiteTurn))) {                Move move = findBestMove(                        possibleMove.getResultChessboard(), depth - 1,                        !maximizingPlayer);                if (move.getValue() > bestMove.getValue()) {                    possibleMove.setValue(move.getValue());                    bestMove = possibleMove;                }            }        } else {            bestMove = new Move(Integer.MAX_VALUE);            for (Move possibleMove : findAllPossibleMoves(chessboard,                    !(maximizingPlayer ^ whiteTurn))) {                Move move = findBestMove(                        possibleMove.getResultChessboard(), depth - 1,                        !maximizingPlayer);                if (move.getValue() < bestMove.getValue()) {                    possibleMove.setValue(move.getValue());                    bestMove = possibleMove;                }            }        }        return bestMove;    }}

可能是算法实现、对象设计或使用中的错误。我无法确定具体问题所在。因此,在尝试优化代码或调整程序的内存配置之前,我想确保没有遗漏任何重大问题。

注意:我没有使用内存分析的经验。


回答:

在国际象棋中,有20种可能的第一步走法(16种由兵走,4种由马走)。

为了简化起见,我们假设接下来的走法也如此。

  • 对于深度1,极小极大算法只考虑这20个走法。
  • 对于深度2,极小极大算法考虑20个走法及其20个回应,共400种可能的走法,没有问题。
  • 对于深度3,极小极大算法考虑20^3 = 8000种可能的走法。在你的机器上已经需要15秒了。
  • 对于深度4,极小极大算法考虑20^4 = 160000种可能的走法。这将比前一个深度多花大约20倍的时间…

简单来说,搜索空间变得太大——它随着输入(深度)大小呈指数增长。时间复杂度为O(20^深度)。

但是,我们不需要搜索所有空间就能找到非常好的走法。

Alpha-beta剪枝是极小极大算法的常用优化方法。

如果这还不够,我会考虑切换到完全不同的算法——例如蒙特卡洛树搜索(带UCT)。

走法数据库也可以帮助——你可以预先计算(预计算)一些开局策略,而不是每次都计算第一步走法。

著名的深蓝在1997年击败卡斯帕罗夫时就使用了这些技术,你可以在这里查看它还使用了什么其他技术。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注