【问题标题】:Minimax algorithm not working for 4x4 TicTacToeMinimax 算法不适用于 4x4 TicTacToe
【发布时间】:2018-09-20 07:24:46
【问题描述】:

好的,所以我写了以下代理,让机器人玩井字游戏。我使用了传统的极小极大算法,没有进行修剪。问题是它非常适合 3x3 板。

但是当我在 4x4 板上运行它时,它会卡住计算。我无法理解为什么。我正在向代理传递一个 numpy 数组 perspectiveState,其中 0 表示空,1 表示代理移动,-1 表示对手移动。它返回其下一步移动的位置 (1)。

控制流程从turn()函数开始,该函数调用minimax()函数。

我在这里做错了什么?

class MiniMaxAgent:

def isMovesLeft(self, perspectiveState):
    size = perspectiveState.shape[0]
    #print('!!', np.abs(perspectiveState).sum())
    if np.abs(perspectiveState).sum() == size*size:
        return False
    return True

def evaluate(self, perspectiveState):
    size = perspectiveState.shape[0]
    rsum = perspectiveState.sum(axis=0)
    csum = perspectiveState.sum(axis=1)
    diagSum = perspectiveState.trace()
    antiDiagSum = np.fliplr(perspectiveState).trace()

    if size in rsum or size in csum or size == diagSum or size == antiDiagSum:
        return 10

    if -1*size in rsum or -1*size in csum or -1*size == diagSum or -1*size == antiDiagSum:
        return -10

    return 0

def minimax(self, perspectiveState, isMax):
    score = self.evaluate(perspectiveState)

    if score == 10:
        return score

    if score == -10:
        return score

    if not self.isMovesLeft(perspectiveState):
        return 0

    if isMax:
        best = -1000
        for i in range(perspectiveState.shape[0]):
            for j in range(perspectiveState.shape[0]):
                if perspectiveState[i,j]==0:
                    perspectiveState[i,j] = 1
                    #print('@', isMax)
                    best = max(best, self.minimax(perspectiveState, not isMax))
                    perspectiveState[i,j] = 0
        #print('#', best)
        return best

    else:
        best = 1000;
        for i in range(perspectiveState.shape[0]):
            for j in range(perspectiveState.shape[0]):
                if perspectiveState[i,j]==0:
                    perspectiveState[i,j] = -1
                    #print('@', isMax)
                    best = min(best, self.minimax(perspectiveState, not isMax))
                    perspectiveState[i,j] = 0
        #print('#', best)
        return best

def turn(self, perspectiveState):
    r,c = perspectiveState.shape
    bestVal = -1000
    bestR, bestC = -1, -1

    for i in range(r):
        for j in range(c):
            if perspectiveState[i,j] == 0:
                perspectiveState[i,j] = 1
                moveVal = self.minimax(perspectiveState, False)
                #undo
                perspectiveState[i,j] = 0
                if moveVal > bestVal:
                    bestVal = moveVal
                    bestR = i
                    bestC = j

    return bestR, bestC

【问题讨论】:

    标签: python numpy artificial-intelligence minimax


    【解决方案1】:

    我使用了传统的极小极大算法没有修剪

    这已经是您问题的答案。这就是为什么修剪和记住过去的状态是算法设计中如此重要的主题。

    如果您将电路板尺寸增加到 4x4,您将获得指数级增长并体验到计算时间的爆炸式增长。如果您估计 3x3 棋盘中可能的移动次数,您将拥有 (3x3)! = 9!,相当于 362 880 次移动。

    如果您现在对 4x4 棋盘上的可能移动执行此操作,您将得到 16 个!可能的状态,这是一个难以置信的大量 20 922 790 000 000 个可能的移动。虽然这些只是近似值,但您可以估计您的计算时间必须超过一百万倍。

    更多解释见:Tic-Tac-Toe minimax algorithm doesn't work with 4x4 board

    【讨论】:

    • 我也做了 alpha beta 修剪。结果没有区别。此外,alpha beta 剪枝仅提供约 25% 的加速。
    • 如果您还实施记忆方法来记住您在搜索树中已经去过的棋盘状态,您将获得更大的加速。 -- 我引用粘贴的链接:对游戏状态数量的估计是:棋盘上的每个方格可以是空的,也可以是 X 或 O。所以这是 3^16 个棋盘。 16!可能的游戏大约是 3^16 种可能的棋盘状态的 50 万倍。这意味着我们大约要计算每块板 50 万次,而不是只计算一次。
    • 哦,好吧。我的代码中是否还有其他固有的错误?
    • 我找不到错误。我认为由于您的算法的一般效率,您只是在与Computational Complexity 斗争。
    • 好的。谢谢你。 :)。如果您认为该问题有帮助,请点赞。
    猜你喜欢
    • 2015-11-03
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多