当前位置: 首页 > 知识库问答 >
问题:

如何在迭代深化中使用计时器停止alpha beta

柯书
2023-03-14

我用alpha-beta修剪创建了一个极大极小函数,我用迭代深化调用它。问题是,当计时器完成时,该函数会一直运行,直到在计时器用完之前,它在开始的深度上完成为止。

我想要的是:当计时器运行完时,minimax函数应该退出并返回none(我将best move保留在minimax之外,请参阅下面的minimax调用代码),或者返回之前计算的best move。我似乎不知道如何在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 

共有1个答案

庄星汉
2023-03-14

我经常使用自定义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 Timeout(5):
    try:
        result = minimax(gamestate, depth, alpha, beta, maximizing_player)
    except TimeoutError:
        result = None
 类似资料:
  • 怎么停止这个计时器,知道吗? 我想重置计时器在每个查询,但它继续。每个新的查询都会添加新的计时器。这个怎么解决?

  • 我的目标是创建一个简单的计时器程序。它不断更新自己,直到按下停止按钮。然而,我不确定如何停止刻度函数运行,以便定时器在按下停止按钮后保持不变。 这是我目前的代码: 停止函数的可能方法是什么? 任何帮助都将不胜感激!

  • 如何知道何时可以停止增加使用negamax alpha beta修剪和换位表的迭代深化算法的深度?以下伪代码取自wiki页面: 这是迭代深化调用: 当然,当我知道游戏中的总移动次数时,我可以使用深度

  • 问题内容: 如果我创建两个列表并将其压缩 然后我将z输入到两个列表中 那么,l1的内容就很好了[(1,7),(2,8),(3,9)],但是l2的内容只是[]。 我猜想这是python关于可迭代项的一般行为。但是,作为从C家族迁移的新手程序员,这对我来说没有意义。为什么会这样表现?有办法解决这个问题吗? 我的意思是,是的,在这个特定示例中,我可以将l1复制到l2中,但是总的来说,在迭代一次之后,是否

  • 我尝试创建一个自定义的时间流逝时间,一旦我按住音量键,它就会启动计时器,并假设时间必须在我松开键后停止,但我松开键时遇到问题,计时器仍在移动。请告诉我我错过了什么谢谢 公共布尔onKeyDown(int-keyCode,KeyEvent-event){if((keyCode==KeyEvent.keyCode_-VOLUME_-DOWN

  • 问题内容: 有人可以教我如何使用a 来达到以下目的: 当我单击鼠标时,我需要一个开始动画的多边形(例如旋转等简单动画);当我再次单击时停止动画。 我对理解工作方式没有任何问题,但对于实际的动画来说,没有任何问题。我尝试在方法中用while块模拟动画,在该方法中我将绘制,擦除和重绘多边形(例如,模拟旋转),但是在while内,applet不会监听点击。它只会在片刻之后收听。单击鼠标时,我需要摆动计时