可能是最简单的强化学习(RL)样例 源代码 注释

感谢莫烦教学视频
强化学习基础知识不赘述,直接开始代码
强化学习=代理选择行为的策略+环境反馈
总100行代码,还是手打环境的情况下。环境部分不属于强化学习。
本次强化学习的方法是QLearning,其核心思想是构建一个二维表格,是当前状态 可选择动作的价值组成
本次的环境是一个一维路径,代理o从最左边开始,重点是最右边T,路径-只能左或者右
看起来是o-----T这样子,当----oT时,代理再往右走一步就到达终点。
从结果可以看出,在第4回合时就已经选择了最短路线了,在最后的Q表中每行right的价值都比left大,说明代理已经知道了向右走比想左走要好。
import numpy as np
import pandas as pd
import time
np.random.seed(2)
N_STATES = 7 # 开始的距离
ACTIONS = ['left', 'right'] # 选的动作
EPSILON = 0.9 # 贪心策略 意思是有90%的概率直接选择之前得分最高的动作
ALPHA = 0.1 # learning rate
LAMBDA = 0.9 # 奖励衰减值 对未来的奖励的在意程度
MAX_EPISODES = 10 # 最大回合数
FRESH_TIME = 0.2 # 刷新时间 这个时间与算法无关,是为了观看
def build_q_table(n_states, actions): # 建立Q表,空的
table = pd.DataFrame(
np.zeros((n_states, len(actions))), # Q_table初始值
columns=actions, # actions name
)
# print(table)
return table
# build_Q_table(N_STATES, ACTIONS)
def choose_action(state, q_table): # 代理选择一个动作
# 选择一个动作
state_actions = q_table.iloc[state, :] # 单独拿出来这一行
if (np.random.uniform() > EPSILON)or(state_actions.all() == 0): # 1-EPSILON 的概率选择随机
action_name = np.random.choice(ACTIONS)
else: # EPSILON的概率选择之前的最好结果的行动
action_name = state_actions.argmax() # 找出最大值的一列
return action_name
# 环境给与反馈 包括走到了哪里,是否走到了终点
def get_env_feedback(S, A):
# 环境反馈
if A == 'right':
if S == N_STATES-2: # 要结束的情况
S_ = 'terminal' # 状态是结束
R = 1
else:
S_ = S+1 # 状态是向右走一步
R = 0
elif A == 'left':
R = 0
if S == 0: # 已经是最左边 则不动
S_ = S
else:
S_ = S-1 # 其他情况向左一步
return S_, R
# 更新环境 主要是用字符串的形式写出来,供看的
def update_env(S, episode, step_counter):
# 环境更新
env_list = ['-']*(N_STATES-1)+['T'] # '-----T'环境就是这样子
if S == 'terminal':
interaction = 'Episode %s: total_steps = %s' % (episode+1, step_counter)
print('\r{}'.format(interaction), end='')
time.sleep(2)
print('\r ', end='')
else:
env_list[S] = 'o'
interaction = ''.join(env_list)
print('\r{}'.format(interaction), end='')
time.sleep(FRESH_TIME)
def rl(): # 主循环
_q_table = build_q_table(N_STATES, ACTIONS)
for episode in range(MAX_EPISODES): # 最多玩这么多回合
step_counter = 0 # 当前回合所使用的步数
S = 0 # 当前的位置(或者说状态)
is_terminated = False # 是否到达终点
update_env(S, episode, step_counter) # 第一步更新环境
while not is_terminated: # 一直走直到终点
A = choose_action(S, _q_table) # 选择一个动作(本例里面是 向左走 向右走)
S_, R = get_env_feedback(S, A) # 得到环境奖励
q_predict = _q_table.ix[S, A] # 估计值
if S_ != 'terminal':
q_target = R + LAMBDA * _q_table.iloc[S_, :].max() # 真实值
else:
q_target = R # 达到目标
is_terminated = True
_q_table.ix[S, A] += ALPHA * (q_target - q_predict) # 新的Q 由 估计值和真实值的差计算出
S = S_ # 状态更新
step_counter += 1
update_env(S, episode, step_counter) # 每走一步更新一下环境
print('\nepisode=', episode, 'step_counter=', step_counter, '\n', _q_table, )
return _q_table
if __name__ == '__main__':
q_table = rl()
print('\r\nQ_table:\n')
print(q_table)