微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用极小极大算法实现迭代深化和 alpha beta 修剪 PYTHON

如何解决使用极小极大算法实现迭代深化和 alpha beta 修剪 PYTHON

我已经使用 alpha beta pruning 实现了 NegaMax 算法(它只是 minimax 算法的一个较短版本)。现在我想实现迭代深化,以便我可以找到每个深度的最佳移动,然后根据前一层的分数重新排序树下的节点,以便我的字母表修剪更有效。

这是我到目前为止所做的:

InitialDEPTH = 1

def findBestMove(gs,validMoves):
    global nextMove
    global InitialDEPTH 
    nextMove = None
    
    for d in range(2):
        CurrentDEPTH = InitialDEPTH + d
        findMoveNegaMaxAlphaBeta(gs,validMoves,CurrentDEPTH,-CHECKMATE,CHECKMATE,1 if gs.whitetoMove else -1)
    
    return nextMove    

这里的 gs 是随着每一个移动而变化的游戏状态,它包含了当时游戏的所有信息,比如是否可以进行castling 或者是否有可能进行快速移动。我的 negamax 算法如下所示:

def findMoveNegaMaxAlphaBeta(gs,depth,alpha,beta,turnMultiplier):
    global nextMove
    if depth == 0 :
       return turnMultiplier * scoreBoard(gs)    

    maxscore = -CHECKMATE

    # I have a felling i need to add some code here to make it work
    for move in validMoves :
        gs.makeMove(move)
        nextMoves = gs.getValidMoves()
        score = -findMoveNegaMaxAlphaBeta(gs,nextMoves,depth - 1,-beta,-alpha,-turnMultiplier)
        if score > maxscore:
            maxscore = score
            if depth == DEPTH :
                nextMove = move
        gs.undoMove() 
        if maxscore > alpha:   # This is were pruning happens
            alpha = maxscore
        if alpha >= beta :
            break    

    return maxscore   

如何将时间约束函数添加到此代码中,以便它仅在提到的时间结束时而不是在此之前返回最佳移动。

此外,我如何在每个深度之后重新排序节点,以便在下一个深度进行有效修剪。我为此编写了某种函数,但我不知道如何实现它。我写的函数

def sorting(move):
    gs.makeMove(move)
    score = scoreBoard(gs)
    gs.undoMove()

    return turnMultiplier * score
validMoves.sort(key = sorting)
    

解决方法

据我所知,您有两个问题,我将尽力回答:

  1. 我如何将时间约束函数添加到此代码中,以便它仅在提到的时间结束时而不是在此之前返回最佳移动。

所以您想在每次移动时搜索特定秒数而不是搜索特定深度?这很容易实现,你所要做的就是让迭代深化到某个大的深度,然后每x个节点比较当前时间和搜索开始时间。像这样:

import time

start_time = time.time()
move_time = 5  # 5 seconds per move
for depth in range(100):
    ...
    score,move = negamax()
    
    # Only save move if you haven't aborted the search at current depth due to time out.
    if move:
        best_score,best_move = score,move

def negamax():
    if time.time() - start_time > move_time:
        return None,None


    ....
    return score,move
  1. 此外,我如何在每个深度之后对节点重新排序,以便在下一个深度进行有效修剪。

我不知道您想用当前的排序做什么。以下是 negamax 框架通常的样子:

def negamax():
    if depth = 0:
        return evaluation()

    valid_moves = gs.get_valid_moves()

    # Here you sort the moves
    sorted_valid_moves = sort(valid_moves)

    for move in sorted_valid_moves():
        gs.make_move()
        score = -negamax(...)
        gs.unmake_move()

您可以根据多个标准对移动进行排序,您可以阅读有关如何实现每个标准的更多信息here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。