本文作者:hhh5460

本文地址:https://www.cnblogs.com/hhh5460/p/10139738.html

例一的代码是函数式编写的,这里用面向对象的方式重新撸了一遍。好处是,更便于理解环境(Env)、个体(Agent)之间的关系。

有缘看到的朋友,自己慢慢体会吧。

0.效果图

1.完整代码

import pandas as pd
import random
import time
import pickle
import pathlib '''
-o---T
# T 就是宝藏的位置, o 是探索者的位置 作者:hhh5460
时间:20181218
地点:Tai Zi Miao
''' class Env(object):
'''环境类'''
def __init__(self):
'''初始化'''
self.env = list('-----T') def update(self, state, delay=0.1):
'''更新环境,并打印'''
env = self.env[:]
env[state] = 'o' # 更新环境
print('\r{}'.format(''.join(env)), end='')
time.sleep(delay) class Agent(object):
'''个体类'''
def __init__(self, alpha=0.01, gamma=0.9):
'''初始化'''
self.states = range(6)
self.actions = ['left', 'right']
self.rewards = [0,0,0,0,0,1] self.alpha = alpha
self.gamma = gamma self.q_table = pd.DataFrame(data=[[0 for _ in self.actions] for _ in self.states],
index=self.states,
columns=self.actions) def save_policy(self):
'''保存Q table'''
with open('q_table.pickle', 'wb') as f:
# Pickle the 'data' dictionary using the highest protocol available.
pickle.dump(self.q_table, f, pickle.HIGHEST_PROTOCOL) def load_policy(self):
'''导入Q table'''
with open('q_table.pickle', 'rb') as f:
self.q_table = pickle.load(f) def choose_action(self, state, epsilon=0.8):
'''选择相应的动作。根据当前状态,随机或贪婪,按照参数epsilon'''
if (random.uniform(0,1) > epsilon) or ((self.q_table.ix[state] == 0).all()): # 探索
action = random.choice(self.get_valid_actions(state))
else:
action = self.q_table.ix[state].idxmax() # 利用(贪婪)
return action def get_q_values(self, state):
'''取状态state的所有Q value'''
q_values = self.q_table.ix[state, self.get_valid_actions(state)]
return q_values def update_q_value(self, state, action, next_state_reward, next_state_q_values):
'''更新Q value,根据贝尔曼方程'''
self.q_table.ix[state, action] += self.alpha * (next_state_reward + self.gamma * next_state_q_values.max() - self.q_table.ix[state, action]) def get_valid_actions(self, state):
'''取当前状态下所有的合法动作'''
valid_actions = set(self.actions)
if state == self.states[-1]: # 最后一个状态(位置),则
valid_actions -= set(['right']) # 不能向右
if state == self.states[0]: # 最前一个状态(位置),则
valid_actions -= set(['left']) # 不能向左
return list(valid_actions) def get_next_state(self, state, action):
'''对状态执行动作后,得到下一状态'''
# l,r,n = -1,+1,0
if action == 'right' and state != self.states[-1]: # 除非最后一个状态(位置),向右就+1
next_state = state + 1
elif action == 'left' and state != self.states[0]: # 除非最前一个状态(位置),向左就-1
next_state = state -1
else:
next_state = state
return next_state def learn(self, env=None, episode=1000, epsilon=0.8):
'''q-learning算法'''
print('Agent is learning...')
for _ in range(episode):
current_state = self.states[0] if env is not None: # 若提供了环境,则更新之!
env.update(current_state) while current_state != self.states[-1]:
current_action = self.choose_action(current_state, epsilon) # 按一定概率,随机或贪婪地选择
next_state = self.get_next_state(current_state, current_action)
next_state_reward = self.rewards[next_state]
next_state_q_values = self.get_q_values(next_state)
self.update_q_value(current_state, current_action, next_state_reward, next_state_q_values)
current_state = next_state if env is not None: # 若提供了环境,则更新之!
env.update(current_state)
print('\nok') def play(self, env=None, delay=0.5):
'''玩游戏,使用策略'''
assert env != None, 'Env must be not None!' if pathlib.Path("q_table.pickle").exists():
self.load_policy()
else:
print("I need to learn before playing this game.")
self.learn(env, 13)
self.save_policy() print('Agent is playing...')
current_state = self.states[0]
env.update(current_state, delay)
while current_state != self.states[-1]:
current_action = self.choose_action(current_state, 1.) # 1., 不随机
next_state = self.get_next_state(current_state, current_action)
current_state = next_state
env.update(current_state, delay)
print('\nCongratulations, Agent got it!') if __name__ == '__main__':
env = Env() # 环境
agent = Agent() # 个体
#agent.learn(env, episode=13) # 先学
#agent.save_policy() # 保存所学
#agent.load_policy() # 导入所学
agent.play(env) # 再玩

最新文章

  1. 2.1、Hibernate多表操作--一对多、多对一、多对多。
  2. iOS 使用AFN 进行单图和多图上传
  3. lr中定义字符串变量
  4. CISCO VPN出现网关报错
  5. windows下安装python,安装框架django。
  6. 3123 高精度练习之超大整数乘法 - Wikioi
  7. Android中的EditText默认时不弹出软键盘的方法
  8. android run process
  9. mybatis中resultType和resultMap的联系
  10. BZOJ_2435_[Noi2011]道路修建_dfs
  11. Centos 6.6 安装
  12. Logback简单使用
  13. Django实战(一)-----用户登录与注册系统1(环境搭建)
  14. 【持续集成】GIT+jenkins+sonar——GIT
  15. 20172309 《Java软件结构与数据结构》实验三报告
  16. 一些常用的mysql语句实例-以后照写2
  17. eclipse 关于*.properties 文件 中文显示为Unicode,无法显示中文的问题(Properties Editor)
  18. Java基础——ArrayList与LinkedList(一)
  19. java future 并发简单实现
  20. 随机模拟MCMC和Gibbs Sampling

热门文章

  1. [20180317]12c TABLE ACCESS BY INDEX ROWID BATCHED2.txt
  2. django模板语言之Template
  3. 纯CSS选项卡
  4. Scoop Windows 的命令行安装程序管理工具
  5. cmder个人配置文件,做个记录
  6. SVN与Git比较的优缺点差异
  7. Mysql基础之 ALTER命令
  8. 用友U8年度账结转 常用凭证丢失
  9. Sring容器技术内幕之InstantiationStrategy类介绍
  10. 模糊查询sql语句条件是中文在后台从数据库查不到结果,是英文和字母就可以,而且统一编码为UTF-8了!!!