【问题标题】:How to stop alpha-beta with a timer in iterative deepening如何在迭代深化中使用计时器停止 alpha-beta
【发布时间】:2021-01-27 20:28:08
【问题描述】:

我创建了一个带有 alpha beta 修剪的 minimax 函数,我用迭代加深来调用它。问题是,当计时器完成时,函数会一直运行,直到它在计时器用完之前开始的深度完成。

我想要什么:当计时器用完时,minimax 函数应该退出并且要么返回 none(我保持最佳移动到 minimax 之外,请参阅下面的 minimax 调用代码),或者返回之前计算的最佳移动。我似乎无法弄清楚如何在 minimax 函数中实现它,我尝试的所有方法都导致它仍然完成了当前的深度。

极小极大函数:

def minimax(gamestate, depth, alpha, beta, maximizing_player):

    if depth == 0 or gamestate.is_check_mate or gamestate.is_stale_mate:
        return None, evaluate(gamestate)

    gamestate.is_white_turn = not maximizing_player
    children = gamestate.get_valid_moves()

    best_move = children[0]

    if maximizing_player:
        max_eval = -math.inf
        for child in children:
            board_copy = copy.deepcopy(gamestate)
            board_copy.make_move(child)
            current_eval = ai_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(gamestate)
            board_copy.make_move(child)
            current_eval = ai_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 

迭代深化的函数调用:

for depth in range(1, max_search_depth):
    time_start = time.time()
    move, evaluation = minimax(gamestate, depth, alpha, beta, maximizing_player)
    time_end = time.time()
    timer = time_end - time_start
    if timer > max_search_time:
        break 

【问题讨论】:

    标签: python minimax alpha-beta-pruning iterative-deepening


    【解决方案1】:

    我经常使用自定义的Timeout 类来解决这类问题。

    import signal
    
    class TimeoutError(Exception):
        """
        Custom error for Timeout class.
        """
    
        pass
    
    
    class Timeout:
        """
        A timeout handler with context manager.
        Based on UNIX signals.
        """
    
        def __init__(self, seconds=1, error_message="Timeout"):
            self.seconds = seconds
            self.error_message = error_message
    
        def handle_timeout(self, signum, frame):
            raise TimeoutError(self.error_message)
    
        def __enter__(self):
            signal.signal(signal.SIGALRM, self.handle_timeout)
            signal.alarm(self.seconds)
    
        def __exit__(self, type, value, traceback):
            signal.alarm(0)
    

    您可以像这样在with statement 中运行递归函数:

    with Timeout(5):
        try:
            result = minimax(gamestate, depth, alpha, beta, maximizing_player)
        except TimeoutError:
            result = None
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-13
      • 2015-07-11
      • 2021-06-04
      • 2021-12-09
      • 2023-04-11
      • 1970-01-01
      相关资源
      最近更新 更多