首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >极大极小函数中的Python深度复制

极大极小函数中的Python深度复制
EN

Stack Overflow用户
提问于 2020-01-06 15:45:55
回答 1查看 439关注 0票数 1

我正在使用带有alpha-beta剪枝的极小极大算法在Python中创建一个国际象棋引擎。然而,目前它非常慢,我发现在minimax中进行每次迭代的深度复制的速度与我所有其他函数的总和一样慢。

有没有办法绕过深度拷贝,或者让它更快?下面是我今天的minimax函数。它只能考虑提前3-4步左右,这并不是一个很好的引擎…任何关于加速算法的建议都是非常感谢的。

代码语言:javascript
复制
def minimax(board, depth, alpha, beta, maximizing_player):

    board.is_human_turn = not maximizing_player 

    children = board.get_all_possible_moves()

    if depth == 0 or board.is_draw or board.is_check_mate:
        return None, evaluate(board)

    best_move = random.choice(children)

    if maximizing_player:
        max_eval = -math.inf
        for child in children:
            board_copy = copy.deepcopy(board)
            board_copy.move(child[0][0], child[0][1], child[1][0], child[1][1])
            current_eval = minimax(board_copy, depth - 1, alpha, beta, False)[1]
            if current_eval > max_eval:
                max_eval = current_eval
                best_move = child
            alpha = max(alpha, current_eval)
            if beta <= alpha:
                break
        return best_move, max_eval

    else:
        min_eval = math.inf
        for child in children:
            board_copy = copy.deepcopy(board)
            board_copy.move(child[0][0], child[0][1], child[1][0], child[1][1])
            current_eval = minimax(board_copy, depth - 1, alpha, beta, True)[1]
            if current_eval < min_eval:
                min_eval = current_eval
                best_move = child
            beta = min(beta, current_eval)
            if beta <= alpha:
                break
        return best_move, min_eval
EN

回答 1

Stack Overflow用户

发布于 2020-01-12 08:09:16

关于如何优化你的程序的一些想法(没有特定的顺序):

1)在minimax函数中做的第一件事就是检查if depth == 0 or board.is_draw or board.is_check_mate。现在你调用board.get_all_possible_moves(),这可能是多余的(例如在depth == 0的例子中)。

2)我不知道get_all_possible_moves()方法是如何实现的,并且假定它不做任何类型的排序。对minimax算法的移动进行排序是一种很好的做法,这样您就可以从最好的节点到最差的节点循环它们(在这种情况下,您可能会修剪更多的节点并加快程序的运行速度)。

3) for child in children循环中的child变量是一个二维矩阵。我还猜测board也是一个多维数组。多维数组可能比一维数组慢,因为它们的内存布局(例如,如果您按列迭代它们)。如果可能,请使用一维数组(例如,您可以将二维数组表示为一维数组的“串联”)。

4)使用生成器进行惰性评估。例如,您可以将get_all_possible_moves()转换为生成器,并在不创建列表和消耗额外内存的情况下对其进行迭代。如果alpha/beta修剪条件提前触发,您将不需要展开位置中的整个子项列表。

5)通过进行和取消当前移动来避免对板子的深度复制。在这种情况下,您不会创建电路板的副本,而是重用原始板,这可能会更快:

current_move_info = ... # collect and store info necessary to make/unmake the current move

board.move(current_move_info)

current_eval = minimax(board, ...)[1]

board.unmake_move(current_move_info) # restore the board position by undoing the last move

6)添加了更多经典的优化国际象棋引擎功能,如迭代加深、主方差搜索、转置表、位板等。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59608390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档