将例二改写成面向对象模式,并加了环境!

不过更新环境的过程中,用到了清屏命令,play()的时候,会有点问题。learn()的时候可以勉强看到:P

0.效果图

1.完整代码

相对于例一,修改的地方:

Agent 五处:states, actions, rewards, get_valid_actions(), get_next_state()

Env    两处:__init__(), update()

import pandas as pd
import random
import time
import pickle
import pathlib
import os '''
四格迷宫:
---------------
| 入口 |      |
---------------
| 陷阱 | 出口 |
---------------
''' class Env(object):
'''环境类'''
def __init__(self):
'''初始化'''
self.env = list('--\n#-') def update(self, state, delay=0.1):
'''更新环境,并打印'''
env = self.env[:]
if state > 1:
state += 1
env[state] = 'o' # 更新环境
print('\r{}'.format(''.join(env)), end='')
time.sleep(delay)
os.system('cls') class Agent(object):
'''个体类'''
def __init__(self, alpha=0.01, gamma=0.9):
'''初始化'''
self.states = range(4) # 状态集。0, 1, 2, 3 四个状态
self.actions = list('udlr') # 动作集。上下左右 4个动作
self.rewards = [0,0,-10,10] # 奖励集。到达位置3(出口)奖励10,位置2(陷阱)奖励-10,其他皆为0 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 % 2 == 1: # 最后一列,则
valid_actions -= set(['r']) # 无向右的动作
if state % 2 == 0: # 最前一列,则
valid_actions -= set(['l']) # 无向左
if state // 2 == 1: # 最后一行,则
valid_actions -= set(['d']) # 无向下
if state // 2 == 0: # 最前一行,则
valid_actions -= set(['u']) # 无向上
return list(valid_actions) def get_next_state(self, state, action):
'''对状态执行动作后,得到下一状态'''
#u,d,l,r,n = -2,+2,-1,+1,0
if state % 2 != 1 and action == 'r': # 除最后一列,皆可向右(+1)
next_state = state + 1
elif state % 2 != 0 and action == 'l': # 除最前一列,皆可向左(-1)
next_state = state -1
elif state // 2 != 1 and action == 'd': # 除最后一行,皆可向下(+2)
next_state = state + 2
elif state // 2 != 0 and action == 'u': # 除最前一行,皆可向上(-2)
next_state = state - 2
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=25, epsilon=0.6) # 先学
#agent.save_policy() # 保存所学
#agent.load_policy() # 导入所学
#agent.play(env) # 再玩

【强化学习】python 实现 q-learning 例四(例二改写)的更多相关文章

  1. 深度强化学习(DQN-Deep Q Network)之应用-Flappy Bird

    深度强化学习(DQN-Deep Q Network)之应用-Flappy Bird 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-fu ...

  2. web前端学习python之第一章_基础语法(二)

    web前端学习python之第一章_基础语法(二) 前言:最近新做了一个管理系统,前端已经基本完成, 但是后端人手不足没人给我写接口,自力更生丰衣足食, 所以决定自学python自己给自己写接口哈哈哈 ...

  3. 机器学习之强化学习概览(Machine Learning for Humans: Reinforcement Learning)

    声明:本文翻译自Vishal Maini在Medium平台上发布的<Machine Learning for Humans>的教程的<Part 5: Reinforcement Le ...

  4. 深度强化学习(Deep Reinforcement Learning)入门:RL base & DQN-DDPG-A3C introduction

    转自https://zhuanlan.zhihu.com/p/25239682 过去的一段时间在深度强化学习领域投入了不少精力,工作中也在应用DRL解决业务问题.子曰:温故而知新,在进一步深入研究和应 ...

  5. 【转】【强化学习】Deep Q Network(DQN)算法详解

    原文地址:https://blog.csdn.net/qq_30615903/article/details/80744083 DQN(Deep Q-Learning)是将深度学习deeplearni ...

  6. Deep learning:四十二(Denoise Autoencoder简单理解)

    前言: 当采用无监督的方法分层预训练深度网络的权值时,为了学习到较鲁棒的特征,可以在网络的可视层(即数据的输入层)引入随机噪声,这种方法称为Denoise Autoencoder(简称dAE),由Be ...

  7. 廖雪峰网站:学习python基础知识—循环(四)

    一.循环 1.for names = ['Michal', 'Bob', 'tracy'] for name in names: print(name) sum = 0 for x in [1, 2, ...

  8. 廖雪峰网站:学习python基础知识—list和tuple(二)

    1.list """ Python内置的一种数据类型是列表:list. list是一种有序的集合,可以随时添加和删除其中的元素. """ c ...

  9. [Reinforcement Learning] 强化学习介绍

    随着AlphaGo和AlphaZero的出现,强化学习相关算法在这几年引起了学术界和工业界的重视.最近也翻了很多强化学习的资料,有时间了还是得自己动脑筋整理一下. 强化学习定义 先借用维基百科上对强化 ...

  10. Deep Learning专栏--强化学习之从 Policy Gradient 到 A3C(3)

    在之前的强化学习文章里,我们讲到了经典的MDP模型来描述强化学习,其解法包括value iteration和policy iteration,这类经典解法基于已知的转移概率矩阵P,而在实际应用中,我们 ...

随机推荐

  1. recovery 升级'@/cache/recovery/block.map' failed错误问题

    随着android版本升级,升级包越来越大,当升级包无法存储在cache分区的时候,会把升级包下载到data分区,然后从data分区升级,最近从data分区加载升级包升级的时候,遇到了如下错误: [ ...

  2. 从零自学Java-8.创建第一个对象

    1.创建对象:2.使用属性描述对象:3.确定对象的行为:4.合并对象:5.从其他对象继承:6.转换对象和其他类型的信息. 程序NewRoot2:计算输入数的算数平方根并输出 package com.j ...

  3. Sql Server 增加字段、修改字段、修改类型、修改默认值

    1.修改字段名: alter table 表名 rename column A to B 2.修改字段类型: alter table 表名 alter column 字段名 type not null ...

  4. FUSE 文件系统 example部分 源码注释 (libfuse 2.9.9)

    本篇文章主要是针对fuse-2.9.9 Example 部分 给出的源码,结合官方文档,以及网上的资料给出注释,希望能给正在学习的你们一点帮助. Hello.c /* FUSE: Filesystem ...

  5. [JSON_01] JSON 解析

    0. 说明 介绍 && 测试 JSON 1. 介绍 XML 指可扩展标记语言(eXtensible Markup Language). XML 被设计用来传输和存储数据. JSON: ...

  6. Unity3d粒子系统详解

  7. 服务器出现大量的127.0.0.1:3306 TIME_WAIT连接 解决方法 [转载]

    netstat -an 192.168.12.13:3306      192.168.12.12:30443      TIME_WAIT 192.168.12.13:3306      192.1 ...

  8. 新鲜出炉的jquery fileupload 插件

    内容属原创,转载请注明出处 为什么做这个东东 项目中需要用到一个多附件上传的控件,找了一圈没找到中意的(唯一一个中意点的还不开源,费用比较高),这不,只得自己抡刀上了. 需求是什么 这么个上传的东东, ...

  9. [Jsoi2015]染色问题

    题目 看到这个限制条件有点多,我们就一直容斥好了 先容斥颜色,我们枚举至少不用\(i\)种颜色 再容斥列,我们枚举至少不用\(j\)列 最后容斥行,枚举至少不用\(k\)行 容斥系数显然是\((-1) ...

  10. WINS服务器与DNS服务器有什么区别?

    1.WINS实现的是IP地址和计算机名称的映射,DNS实现的是IP地址和域名的映射.2.WINS作用的范围是某个内部网络,DNS的范围是整个互联网.简单说明一下:WINS实现的是IP地址和计算机名称的 ...