Descripción del problema: El
problema es similar a una máquina tragamonedas (máquina de juego de un solo brazo). La diferencia es que tiene k palancas. Cada acción equivale a tirar de una palanca de la máquina tragamonedas. Esperamos que a través del aprendizaje reforzado, el agente pueda Al elegir repetidamente aprender, para maximizar el valor final de la bonificación.
Resultados recurrentes:
visualización del entorno: el azul es el beneficio real de cada botón; el verde es el beneficio estimado del agente para el botón; el rojo es la elección del agente.
Realización del código
1. Construcción del entorno:
import numpy as np
global value
value = np.array([0.0]*10, dtype=float) #初始化全局变量
q = np.array([-8,-5,-2,1,5,6,1,2,8,0]) # 固定生成收益初始值
#q = np.random.normal(0, 5, 10) # 正态随机收益初始值
qq = np.random.normal(0, 0.01, 10)
print(q)
def env2():
for i in range(0, 10):
global value
value[i] = np.random.normal(q[i]+qq[i], 1, 1)
return value
2. Producción de GIF
import numpy as np
import random
import matplotlib.pyplot as plt
import matplotlib.animation as animation # 绘制动图的库
plt.rcParams['font.sans-serif'] = ['SimHei'] # 正确显示中文
plt.rcParams['axes.unicode_minus'] = False # 正确显示正负号
from env import env1,env2 # 导入自己编写的环境
# 超参数
EPSILON = 0.1 # epsilon-贪心
global n
n = 180 # 步长
K = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) # 存储action
# 全局变量声明及其初始化
global actions_q # 环境中10个action的实际收益
actions_q = np.array([0.0] * 10, dtype=float)
global actions_Q # 智能体对10个action的估计收益
actions_Q = np.array([0.0] * 10, dtype=float)
global value_total # 过去获得的总收益
value_total = 0
global actions_num # 存储10个action选择到的次数
actions_num = np.array([0] * 10, dtype=int)
global right_num # 存储选对的次数
right_num = 0
# 动图描述
fig, (ax0, ax1, ax2) = plt.subplots(3, 1)
ln1, = ax0.plot([], [], "bo", animated=True) # 绘制环境value变化量
ln2, = ax0.plot([], [], "ro", animated=True) # 绘制选择的action
ln3, = ax0.plot([], [], "g*", animated=True) # 绘制智能体预测的Q值
text_pt = ax0.text(-0.8, 8, '', fontsize=12) # 写入文字
x, y1, y2 = [], [], []
ln4, = ax1.plot([], [], "-", animated=True) # 绘制智能体预测的Q值
ln5, = ax2.plot([], [], "-", animated=True) # 绘制智能体预测的Q值
def init(): # 画布坐标轴范围初始化
global n
ax0.set_title("环境可视化")
ax0.set_xlabel("键位")
ax0.set_ylabel("收益")
ax0.set_xlim(-1, 10)
ax0.set_ylim(-15, 15) # 环境可视化
ax1.set_ylabel("平均正确率")
ax1.set_xlabel("步数")
ax1.set_xlim(0, n)
ax1.set_ylim(0, 1) # 平均正确率
ax2.set_ylabel("平均收益")
ax2.set_xlabel("步数")
ax2.set_xlim(0, n)
ax2.set_ylim(0, 10) # 平均收益
plt.tight_layout()
return ln1, ln2, ln3, ln4, ln5, text_pt,
def update(frame): # 回合更新
global actions_q
actions_q = env2() # 获取现在环境中的真实收益(数组形式)
global actions_Q
if np.random.uniform() > EPSILON: # 90%的概率 greedy
arr_aa = np.array(actions_Q, dtype=float)
action = np.argmax(arr_aa) # 从估计值中选择最大的动作为action
# print("贪婪,选择了:")
# print(action)
else:
action = random.choice(K) # 随机选择action
# print("随机,选择了:")
# print(action)
global actions_num
actions_num[action] += 1 # 存储各个action被选择的次数
arr_aa = np.array(actions_q, dtype=float)
action_right = np.argmax(arr_aa) # 实际上收益最大的action
if (action == action_right):
global right_num
right_num += 1
global value_total
value_total += actions_q[action] # 存储
ln1.set_data(K, actions_q) # 绘制环境中真实收益值
ln2.set_data(action, actions_q[action]) # 标记本回合选择的action
ln3.set_data(K, actions_Q) # 绘制智能体的估计值
text_pt.set_text("第%d回合" % (frame)) # 绘制回合数
x.append(frame) # 将每次传过来的n追加到xdata中
y1.append(right_num / frame)
ln4.set_data(x, y1)
y2.append(value_total / frame)
ln5.set_data(x, y2)
R = actions_q[action] # 环境中的真实收益
num = actions_num[action] # 第num次选择这个动作
# 方法一:平均收益法更新估计值
actions_Q[action] = actions_Q[action] + (R - actions_Q[action]) / float(num)
# 方法二:固定步长法更新估计值
# actions_Q[action] = actions_Q[action] + 0.1*(actions_q[action]-actions_Q[action])
return ln1, ln2, ln3, ln4, ln5, text_pt,
# 绘制动画
anim = animation.FuncAnimation(fig, update, np.arange(1, n), interval=10, blit=True, init_func=init)
# 存储为gif动图
# anim.save("1.gif", writer='pillow')
plt.show()