Usaremos o algoritmo de value iteration, apresentado na figura 4.5 do livro Reinforcement Learning de Sutton and Barto. O código é seguinte:
"""
Created on Thu Jul 7 17:16:26 2016
@author: Leonardo Marinho
O codigo abaixo implementa o exemplo 4.3 do livro Reinforcement Learning
de Sutton and Barto. É a solução para a questão 7 da Aula 25 de Métodos
Computacionais em Economia - Aprendizagem de Máquinas: Aprendizagem por
Reforço.
"""
import numpy as np
import matplotlib.pyplot as plt
def reward(state_plus_action):
"""
Funcao que determina o valor esperado da recompensa dados a acao e o
estado. Note que, como no nosso exemplo so ha recompensa se a acao e o
estado somarem 100, na pratica a funcao so depende desta soma.
"""
if state_plus_action == 100:
return .4
else:
return 0
def max_sum(state, value):
"""
Funcao que calcula o somatorio da figura 4.5 do livro, que representa o
argumento a ser maximizado na equacao de Bellman. Ela recebe o estado e
a funcao valor (em formato de vetor) e retorna um vetor com o maximo
entre os somatorios em funcao das acoes na primeira componente, e um
argumanto (acao), que atinge este maximo, na segunda componente. Este
argumento serve para calcular a policy function.
"""
actions = range(min([state, 100 - state]) + 1)
somatorio = np.array([0.]*len(actions))
for action in actions:
next_state_plus = state + action
next_state_minus = state - action
somatorio[action] = .4 * (reward(next_state_plus) +
value[next_state_plus]) +\
.6 * value[next_state_minus]
return [np.max(somatorio), np.argmax(somatorio)]
# O loop abaixo implementa o algoritmo da figura 4.5 do livro e retorna a
# funcao valor para o problema apos a convergencia
value = np.array([0.]*101)
while True:
delta = 0.
for state in (np.array(range(99))+1):
v = value[state]
value[state] = max_sum(state, value)[0]
delta = np.max([delta, np.abs(v - value[state])])
plt.plot(value)
if delta < 0.0001:
break
# O comando abaixo calcula uma policy function com base na funcao valor
# calculada anteriormente. Note que a policy function nao e unica
policy = [max_sum(i, value)[1] for i in (np.array(range(99))+1)]
O código gera o gráfico com a evolução da aprendizagem da value function:
