В контексте проекта, следуя проекту UC Berkley pacman ai (его вторая часть), я хочу реализовать минимаксный алгоритм, без альфа-бета-отсечения, для агента соперника в достаточно малой компоновке, чтобы рекурсия непроблема.
Определив задачу как игру с 2 игроками (мы предполагаем, что у нее только 1 призрак), игра с нулевым результатом и идеальной информацией с применением рекурсии была бы довольно тривиальной. Тем не менее, поскольку многие разные стратегии могут оказаться в одном и том же игровом состоянии (определяемом как кортеж позиции Пакмана, позиции призрака, позиции еды и игрока, играющего в данный момент), я хотел найти способ избежать пересчета всех этих состояний.
Я искал и читал кое-что о таблицах транспонирования. Однако я не совсем уверен, как использовать такой метод, и я подумал, что должен реализовать следующее: каждый раз, когда состояние, еще не посещенное, расширяется, добавляйте его в набор «посещенных». Если состояние уже было расширено, то если это максимальный ход игрока (pacman), верните значение + inf (которое обычно никогда не будет выбрано минимальным игроком), если его ход за минутой вернет -inf соответственно.
Проблема с этой идеей, я думаю, и причина, по которой она работает для некоторых макетов, но не для других, заключается в том, что когда я нажимаю на узел, все дочерние элементы которого уже раскрыты, единственные значения, которые я должен выбрать, это+/- бесконечности. Это заставляет бесконечное значение распространяться вверх и выбираться, хотя на самом деле возможно, что это игровое состояние приведет к проигрышу. Я думаю, я понял проблему, но я не могу найти способ обойти ее.
Есть ли какой-нибудь другой метод, который я мог бы использовать, чтобы избежать вычисления повторяющихся состояний игры? Есть ли стандартный подход к этому, о котором я не знаю?
Вот какой-то псевдокод:
def maxPLayer(currentState, visitedSet):
if not isTerminalState
for nextState, action in currentState.generateMaxSuccessors()
if nextState not in visitedSet
mark nextState as visited
scores = scores + [minPlayer(nextState, visitedSet)]
if scores is not empty
return bestScore = max(scores)
else
return +inf #The problem is HERE!
else
return evalFnc(currentState)
end MaxPlayer
def minPlayer(currenstState, visitedSet):
if not isTerminal
for nextState, action in generateMinSuccessors()
if nextState not in visitedSet
mark nextState as visited
scores = scores + [maxPLayer(nextState, visitedSet)]
if scores is not empty
return bestScore = min(scores)
else
return -inf #The problem is also HERE!
else
return evalFnc(currentState)
end MinPlayer
Обратите внимание, что первый игрок, который будет играть, это Макс, и я выбираю действие, которое имеетсамый высокий балл. Ничего не меняется, если я принимаю во внимание бесконечные значения или нет, все еще есть случаи, когда агент проигрывает или повторяет бесконечно.