上下左右
和复制粘贴
这六个动作的情况下 学会如何将上一行的文字复制到输出框可玩: 状态有限, 动作有限. (其中一个 精确的解.)
不可玩: 状态无限 或 动作无限. (其中一个 近似的解.)
O
代表寻宝者的所在游戏中的位置
—
代表路径
T
代表宝藏的位置
O
可执行的动作只有 左
和 右
它找到宝藏就是最大化收益
它会的动作只有左
和右
它可随机出现在整个地图上的任何位置, 并试图找到宝藏
class Game_env():
def get_env_feedback(self, state, action):
...
# 输入给环境当前的状态 和 需要执行的动作
# 返回下一个状态 和 下一个状态给的奖励
# 例如输入: ---O-T 状态为:3 动作为: right
# 那么输出: ----OT 状态为:4 奖励为: 0
def update_env(self, state, round, step_counter):
...
# 根据状态更新当前环境,并可视化.
# 输入为 state=3
# 输出为 可视化当前状态 终端显示: ---O-T Treasure 宝物,财富.等意思...
# round 和 step_counter 用于记录和显示 当前的回合数,和完成一回合游戏所使用的步数.可不使用
class Play_game():
def build_q_table(self, n_states, actions):
...
# 创建q表 用于指导智能体如何玩游戏
# state left right
# 0 0.0 0.0
# 1 0.0 0.0
# 2 0.0 0.0
# 3 0.0 0.0
# 4 0.0 0.0
# 这里可以写成活的q表 判断如果没有此状态则添加.
# 这里可以扩展到 二维的迷宫游戏或其它 状态有限 动作有限 的游戏
# state left right down up
# 0 0.0 0.0 0.0 0.0
# 1 0.0 0.0 0.0 0.0
# 2 0.0 0.0 0.0 0.0
# 3 0.0 0.0 0.0 0.0
# 4 0.0 0.0 0.0 0.0
def choose_action(self, state):
...
# 根据贪婪率选择随机动作或最大收益动作(电脑自动玩游戏)
# 也可玩家手动指导智能体玩游戏只需将选择动作的代码改为键盘输入即可(人工指导智能体玩游戏)
# 输入当前状态 例如: ---O-T 状态为: 3
# 返回输出动作 例如: left 或者 right
class Train():
def learning_round(self):
...
# 设置每个回合配置 如下:
# 1. 初始状态 置零或随机
# 2. 游戏状态 置为未完成
# 3. 游戏进行步数 置零
# 4. 游戏环境初始化
# 开始学习q表
def learning_steps(self, state, is_terminated, round, step_count):
...
# 整个游戏初始化后就可以开始玩了.
# 无限死循环 或者 玩多少步后强制退出都行
# 1. 选择一个动作 -> 得到一个动作
# 2. 获得环境的反馈 -> 得到 下一个状态 和 奖励
# 3. 得到q真实的值 -> 当前的状态 和 选择的动作 确定q真实的值
# 4. 得到q估计的值 -> 下一步动作的奖励 + 远见 * 下一个状态的所有动作值中的最大值
# 5. 更新q表的值 -> 学习率 * (q估计 - q现实)
# 6. 更新当前的状态 -> 当前状态为选择动作后的下一个状态
# 7. 更新当前的环境
# 8. 当前回合步数统计, 可省略.
# 进入下一个回合, 重置游戏各项参数.重新开始玩.
# state left right
# 0 0.0 0.0
# 1 0.0 0.0
# 2 0.0 0.0
# 3 0.0 0.0
# 4 0.0 0.0
Q ( s t , a t ) ← Q ( s t , a t ) + α ⋅ ( r t + γ ⋅ m a x Q ( s t + 1 , a ) − Q ( s t , a t ) ) Q\left (s_{t}, a_{t}\right) \leftarrow Q\left (s_{t}, a_{t} \right)+\alpha \cdot \left(r_{t} +\gamma \cdot maxQ \left (s_{t+1},a \right)-Q \left (s_{t}, a_{t} \right) \right) Q(st,at)←Q(st,at)+α⋅(rt+γ⋅maxQ(st+1,a)−Q(st,at))
import time
import pandas as pd
import numpy as np
class Game_env():
def __init__(self, N_STATES=5, FRESH_TIME=0.3):
self.N_STATES = N_STATES # the length of the 1 dimensional world 状态长度
self.FRESH_TIME = FRESH_TIME # fresh time for one move
def get_env_feedback(self, state, action):
if action == 'right': # move right
if state == self.N_STATES - 1: # terminate 0 start
next_state = 'terminal'
reward = 1
else:
next_state = state + 1
reward = 0
else: # move left
reward = 0
if state == 0:
next_state = state # reach the wall
else:
next_state = state - 1
return next_state, reward
def update_env(self, state, round, step_counter):
env_list = ['-']*(self.N_STATES) + ['T'] # '-----T' our environment
if state == 'terminal':
interaction = 'Round: %s Total_move_steps: %s' % (round+1, step_counter)
print('\r{}'.format(interaction), end='')
time.sleep(3)
print('\r ', end='')
else:
env_list[state] = 'o'
interaction = ''.join(env_list)
print('\r{}'.format(interaction), end='')
time.sleep(self.FRESH_TIME)
class Play_game():
def __init__(self, N_STATES=5):
self.N_STATES = N_STATES # the length of the 1 dimensional world
self.ACTIONS = ['left', 'right'] # available actions
self.EPSILON = 0.9 # greedy 有多大概率选择最优动作
self.q_table = self.build_q_table(self.N_STATES, self.ACTIONS)
def build_q_table(self, n_states, actions):
table = pd.DataFrame(np.zeros((n_states, len(actions))), columns=actions, )
print("\n init q_table: \n", table)
return table
def choose_action(self, state):
state_actions = self.q_table.iloc[state, :]
if (np.random.uniform() > self.EPSILON) or ((state_actions == 0).all()):
action_name = np.random.choice(self.ACTIONS)
else: # act greedy
action_name = state_actions.idxmax()
return action_name
class Train():
def __init__(self, learn_round=13):
N_STATES = 5
self.game_env = Game_env(N_STATES)
self.play = Play_game(N_STATES)
self.learn_round = learn_round
self.ALPHA = 0.1 # learning rate
self.GAMMA = 0.9 # discount factor # 远见
def learning_round(self):
for round in range(self.learn_round):
state = 0
is_terminated = False
step_count = 0
self.game_env.update_env(state, round, step_count)
self.learning_steps(state, is_terminated, round, step_count)
# print("\n" + "=" * 20 + "\n q_table round: {}\n".format(round + 1), self.play.q_table)
return self.play.q_table
def learning_steps(self, state, is_terminated, round, step_count):
while not is_terminated:
action = self.play.choose_action(state)
next_state, reward = self.game_env.get_env_feedback(state, action)
q_predict = self.play.q_table.loc[state, action]
if next_state != 'terminal':
q_target = reward + self.GAMMA * self.play.q_table.iloc[next_state, :].max()
else:
q_target = reward # next state is terminal
is_terminated = True # terminate this episode
self.play.q_table.loc[state, action] += self.ALPHA * (q_target - q_predict) # update
state = next_state # move to next state
self.game_env.update_env(state, round, step_count + 1)
step_count += 1
if __name__ == '__main__':
pass
# # env show
# game_env = Game_env()
# action = "left"
# next_state, reward = game_env.get_env_feedback(state=4, action=action)
# print("下一个状态:{}\n下一个状态所给予的奖励:{}".format(next_state, reward))
# game_env.update_env(next_state, round=1, step_counter=10)
# # play show
# play = Play_game()
# action = play.choose_action(state=4)
# print("选择的动作名字:", action)
# # learning
# agent = Train()
# learn_result = agent.learning_round()
# print("\n 最后保存的q_table", learn_result)