使用带有 alpha beta 剪枝的 minimax 算法实现迭代加深 PYTHON
Implementing Iterative Deepening with minimax algorithm with alpha beta pruning PYTHON
我已经实现了一个带有 alpha beta 剪枝的 NegaMax 算法(它只是 minimax 算法的一个较短版本)。现在我想实现迭代深化,以便我可以为每个深度找到最佳移动,然后根据前几层的分数对树下的节点重新排序,以便我的 alphabeta 修剪工作更有效。
这是我目前所做的:
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 是随着每一步移动而变化的游戏状态,它包含了当时游戏的所有信息,比如是否可以易位或是否可以进行顺势移动。我的 negamax 算法如下所示:
def findMoveNegaMaxAlphaBeta(gs, validMoves, 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
我如何将时间限制功能添加到此代码中,以便它仅在提到的时间结束时 returns 最佳移动,而不是在此之前。
另外,如何在每个深度之后重新排序节点以便在下一个深度进行有效修剪。我已经为此编写了某种功能,但我不知道如何实现它。我写的函数:
def sorting(move):
gs.makeMove(move)
score = scoreBoard(gs)
gs.undoMove()
return turnMultiplier * score
validMoves.sort(key = sorting)
据我所知,您有 2 个问题,我将尝试回答这些问题:
- 如何将时间限制功能添加到此代码中,以便它仅在上述时间结束时 returns 最佳移动,而不是在此之前。
所以你想搜索每次移动的特定秒数而不是搜索特定深度?这很容易实现,你所要做的就是让迭代加深到某个较大的深度,然后每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
- 另外,如何在每个深度后重新排序节点以便在下一个深度进行有效修剪。
我不知道您要对当前排序做什么。下面是 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。
我已经实现了一个带有 alpha beta 剪枝的 NegaMax 算法(它只是 minimax 算法的一个较短版本)。现在我想实现迭代深化,以便我可以为每个深度找到最佳移动,然后根据前几层的分数对树下的节点重新排序,以便我的 alphabeta 修剪工作更有效。
这是我目前所做的:
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 是随着每一步移动而变化的游戏状态,它包含了当时游戏的所有信息,比如是否可以易位或是否可以进行顺势移动。我的 negamax 算法如下所示:
def findMoveNegaMaxAlphaBeta(gs, validMoves, 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
我如何将时间限制功能添加到此代码中,以便它仅在提到的时间结束时 returns 最佳移动,而不是在此之前。
另外,如何在每个深度之后重新排序节点以便在下一个深度进行有效修剪。我已经为此编写了某种功能,但我不知道如何实现它。我写的函数:
def sorting(move):
gs.makeMove(move)
score = scoreBoard(gs)
gs.undoMove()
return turnMultiplier * score
validMoves.sort(key = sorting)
据我所知,您有 2 个问题,我将尝试回答这些问题:
- 如何将时间限制功能添加到此代码中,以便它仅在上述时间结束时 returns 最佳移动,而不是在此之前。
所以你想搜索每次移动的特定秒数而不是搜索特定深度?这很容易实现,你所要做的就是让迭代加深到某个较大的深度,然后每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
- 另外,如何在每个深度后重新排序节点以便在下一个深度进行有效修剪。
我不知道您要对当前排序做什么。下面是 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。