Python 如何在迭代过程中使用计时器停止alpha beta
我用alpha-beta修剪创建了一个minimax函数,我用迭代深化调用它。问题是,当定时器完成时,该函数会一直运行,直到它在定时器用完之前的深度上完成 我想要的:当计时器运行完时,minimax函数应该退出并返回none(我将best move保留在minimax之外,请参阅下面的minimax调用代码),或者返回先前计算的best move。我只是想不出如何在minimax函数中实现它,我尝试的每件事都使它仍然完成了当前的深度 极小极大函数:Python 如何在迭代过程中使用计时器停止alpha beta,python,minimax,alpha-beta-pruning,iterative-deepening,Python,Minimax,Alpha Beta Pruning,Iterative Deepening,我用alpha-beta修剪创建了一个minimax函数,我用迭代深化调用它。问题是,当定时器完成时,该函数会一直运行,直到它在定时器用完之前的深度上完成 我想要的:当计时器运行完时,minimax函数应该退出并返回none(我将best move保留在minimax之外,请参阅下面的minimax调用代码),或者返回先前计算的best move。我只是想不出如何在minimax函数中实现它,我尝试的每件事都使它仍然完成了当前的深度 极小极大函数: def minimax(gamestate,
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
我经常使用自定义的
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
with Timeout(5):
try:
result = minimax(gamestate, depth, alpha, beta, maximizing_player)
except TimeoutError:
result = None