如何通过内存和迭代加深提高我的 alpha beta 剪枝极小极大算法的性能

How do I increase the performance of my alpha beta pruning minimax algorithm with memory and iterative deepening

我在 python 中创建了一个类似于井字游戏的游戏,我可以在其中选择棋盘的大小和连续获胜所需的棋子数量。我还创建了一个具有 minimax、alpha-beta 修剪、转置表和迭代加深的机器人。我正在使用 python 并且我的板表示只是一个二维数组。出于某种原因,当国际象棋引擎每秒计算 100,000 多个节点时,我的算法每秒只计算 600 个节点。我知道 python 很慢而且板的表示会影响速度,但我认为它不应该只计算每秒 600 个左右的节点。我还有一个评估功能,可以对整个棋盘进行循环并评估棋子的位置。我只是想弄清楚如何加速算法,因为它看起来慢得不合理。

我的算法:

def tt_minimax(board, plr, alpha, beta, depth):
    global tt_start_time
    if ITERATIVEDEEPENING and timeit.default_timer()-tt_start_time >= MAXTIME:
        return "UNFINISHED", 0

    alpha_org = alpha

    tt_code = tt_hash(board)
    pv_move = []
    if tt_code in TRANSPOSITION_TABLE:
        tt_entry = TRANSPOSITION_TABLE[tt_code]
        if tt_entry[3] >= depth:
            if tt_entry[2] == 0:  # checking for Exact
                return tt_entry[0], tt_entry[1]
            elif tt_entry[2] == -1:  # lower bound
                alpha = max(alpha, tt_entry[1])
            elif tt_entry[2] == 1:  # upper bound
                beta = min(beta, tt_entry[1])

            if alpha >= beta:
                return tt_entry[0], tt_entry[1]
        else:
            pv_move = tt_entry[0]

    global tt_node_count
    tt_node_count += 1

    moves = find_moves(board)
    #random.shuffle(moves)

    if pv_move:
        moves.insert(0, moves.pop(moves.index(pv_move)))

    # if drawn
    if len(moves) == 0:
        return "none", 0

    # maximizing
    if plr == 1:

        best_score = MIN
        best_move = []
        for movePair in moves:
            y, x = movePair[0], movePair[1]
            board[y][x] = plr

            wt_code = tt_hash(board)
            if wt_code in WIN_TABLE:
                test_result = WIN_TABLE[wt_code]
            else:
                test_result = test_for_win(board)
                WIN_TABLE[wt_code] = test_result

            if test_result == plr:
                evaluation = 1000 + TTD + depth
                if evaluation > best_score:
                    best_score = evaluation
                    best_move = movePair
            elif depth > 0:
                returned = tt_minimax(board, 2, alpha, beta, depth - 1)
                if returned[0] == "UNFINISHED":
                    return returned
                return_eval = returned[1]
                if return_eval > best_score:
                    best_score = return_eval
                    best_move = movePair
            else:
                evaluation = evaluate(board, 2)
                if evaluation > best_score:
                    best_score = evaluation
                    best_move = movePair

            board[y][x] = 0
            alpha = max(alpha, best_score)

            if beta <= alpha:
                break

        tt_store(TRANSPOSITION_TABLE, board, alpha_org, beta,
                 best_move, best_score, depth)

        return best_move, best_score

    # minimizing
    else:
        best_score = MAX
        best_move = []
        for movePair in moves:
            y, x = movePair[0], movePair[1]
            board[y][x] = plr

            wt_code = tt_hash(board)
            if wt_code in WIN_TABLE:
                test_result = WIN_TABLE[wt_code]
            else:
                test_result = test_for_win(board)
                WIN_TABLE[wt_code] = test_result

            if test_result == plr:
                evaluation = -1000 - depth
                if evaluation < best_score:
                    best_score = evaluation
                    best_move = movePair
            elif depth > 0:
                returned = tt_minimax(board, 1, alpha, beta, depth - 1)
                if returned[0] == "UNFINISHED":
                    return returned
                return_eval = returned[1]
                if return_eval < best_score:
                    best_score = return_eval
                    best_move = movePair
            else:
                evaluation = evaluate(board, 2)
                if evaluation < best_score:
                    best_score = evaluation
                    best_move = movePair

            board[y][x] = 0
            beta = min(beta, best_score)

            if beta <= alpha:
                break

        tt_store(TRANSPOSITION_TABLE, board, alpha_org, beta,
                 best_move, best_score, depth)

        return best_move, best_score

C 比 Python 快一点。 C 比 Python 快很多。将其转换为 C 将是巨大的。然后你可以再问一次,因为用 C 语言编码的方式也很庞大。以更快的速度乘以数十,你的程序将在 C 中尖叫。

Python,好吧,我只想说Python并不意味着快。在 Python 的初始设计中速度不是一个因素,现在一切都是对象......可以这么说 Python 变得更好时变得更慢。我喜欢 Python 的目的,但 C 也有目的。您的程序是 C 的用途的完美示例。使用 Python 作为包装器来玩游戏。用C计算下一步。