【强化学习】python 实现 q-learning 迷宫通用模板
本文作者:hhh5460
本文地址:https://www.cnblogs.com/hhh5460/p/10145797.html
0.说明
这里提供了二维迷宫问题的一个比较通用的模板,拿到后需要修改的地方非常少。
对于任意的二维迷宫的 class Agent,只需修改三个地方:MAZE_R, MAZE_R, rewards,其他的不要动!如下所示:
class Agent(object):
'''个体类'''
MAZE_R = 6 # 迷宫行数
MAZE_C = 6 # 迷宫列数 def __init__(self, alpha=0.1, gamma=0.9):
'''初始化'''
# ... ...
self.rewards = [0,-10,0, 0, 0, 0,
0,-10,0, 0,-10, 0,
0,-10,0,-10, 0, 0,
0,-10,0,-10, 0, 0,
0,-10,0,-10, 1, 0,
0, 0,0,-10, 0,10,] # 奖励集。出口奖励10,陷阱奖励-10,元宝奖励1
# ... ...
1.完整代码
import pandas as pd
import random
import time
import pickle
import pathlib
import os
import tkinter as tk '''
6*6 的迷宫:
-------------------------------------------
| 入口 | 陷阱 | | | | |
-------------------------------------------
| | 陷阱 | | | 陷阱 | |
-------------------------------------------
| | 陷阱 | | 陷阱 | | |
-------------------------------------------
| | 陷阱 | | 陷阱 | | |
-------------------------------------------
| | 陷阱 | | 陷阱 | 元宝 | |
-------------------------------------------
| | | | 陷阱 | | 出口 |
------------------------------------------- 作者:hhh5460
时间:20181219
地点:Tai Zi Miao
''' class Maze(tk.Tk):
'''环境类(GUI)'''
UNIT = 40 # pixels
MAZE_R = 6 # grid row
MAZE_C = 6 # grid column def __init__(self):
'''初始化'''
super().__init__()
self.title('迷宫')
h = self.MAZE_R * self.UNIT
w = self.MAZE_C * self.UNIT
self.geometry('{0}x{1}'.format(h, w)) #窗口大小
self.canvas = tk.Canvas(self, bg='white', height=h, width=w)
# 画网格
for c in range(1, self.MAZE_C):
self.canvas.create_line(c * self.UNIT, 0, c * self.UNIT, h)
for r in range(1, self.MAZE_R):
self.canvas.create_line(0, r * self.UNIT, w, r * self.UNIT)
# 画陷阱
self._draw_rect(1, 0, 'black') # 在1列、0行处,下同
self._draw_rect(1, 1, 'black')
self._draw_rect(1, 2, 'black')
self._draw_rect(1, 3, 'black')
self._draw_rect(1, 4, 'black')
self._draw_rect(3, 2, 'black')
self._draw_rect(3, 3, 'black')
self._draw_rect(3, 4, 'black')
self._draw_rect(3, 5, 'black')
self._draw_rect(4, 1, 'black')
# 画奖励
self._draw_rect(4, 4, 'yellow')
# 画玩家(保存!!)
self.rect = self._draw_rect(0, 0, 'red')
self.canvas.pack() # 显示画作! def _draw_rect(self, x, y, color):
'''画矩形, x,y表示横,竖第几个格子'''
padding = 5 # 内边距5px,参见CSS
coor = [self.UNIT * x + padding, self.UNIT * y + padding, self.UNIT * (x+1) - padding, self.UNIT * (y+1) - padding]
return self.canvas.create_rectangle(*coor, fill = color) def move_agent_to(self, state, step_time=0.01):
'''移动玩家到新位置,根据传入的状态'''
coor_old = self.canvas.coords(self.rect) # 形如[5.0, 5.0, 35.0, 35.0](第一个格子左上、右下坐标)
x, y = state % 6, state // 6 #横竖第几个格子
padding = 5 # 内边距5px,参见CSS
coor_new = [self.UNIT * x + padding, self.UNIT * y + padding, self.UNIT * (x+1) - padding, self.UNIT * (y+1) - padding]
dx_pixels, dy_pixels = coor_new[0] - coor_old[0], coor_new[1] - coor_old[1] # 左上角顶点坐标之差
self.canvas.move(self.rect, dx_pixels, dy_pixels)
self.update() # tkinter内置的update!
time.sleep(step_time) class Agent(object):
'''个体类'''
MAZE_R = 6 # 迷宫行数
MAZE_C = 6 # 迷宫列数 def __init__(self, alpha=0.1, gamma=0.9):
'''初始化'''
self.states = range(self.MAZE_R * self.MAZE_C) # 状态集。0~35 共36个状态
self.actions = list('udlr') # 动作集。上下左右 4个动作 ↑↓←→ ←↑→↓↖↗↘↙
self.rewards = [0,-10,0, 0, 0, 0,
0,-10,0, 0,-10, 0,
0,-10,0,-10, 0, 0,
0,-10,0,-10, 0, 0,
0,-10,0,-10, 1, 0,
0, 0,0,-10, 0,10,] # 奖励集。出口奖励10,陷阱奖励-10,元宝奖励5
#self.hell_states = [1,7,13,19,25,15,31,37,43,10] # 陷阱位置 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.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()): # 探索
if random.uniform(0,1) > epsilon: # 探索
action = random.choice(self.get_valid_actions(state))
else:
#action = self.q_table.ix[state].idxmax() # 利用 当有多个最大值时,会锁死第一个!
#action = self.q_table.ix[state].filter(items=self.get_valid_actions(state)).idxmax() # 重大改进!然鹅与上面一样
s = self.q_table.ix[state].filter(items=self.get_valid_actions(state))
action = random.choice(s[s==s.max()].index) # 从可能有多个的最大值里面随机选择一个!
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.MAZE_C == 0: # 首行,则 不能向上
valid_actions -= set(['u'])
elif state // self.MAZE_C == self.MAZE_R - 1: # 末行,则 不能向下
valid_actions -= set(['d']) if state % self.MAZE_C == 0: # 首列,则 不能向左
valid_actions -= set(['l'])
elif state % self.MAZE_C == self.MAZE_C - 1: # 末列,则 不能向右
valid_actions -= set(['r']) return list(valid_actions) def get_next_state(self, state, action):
'''对状态执行动作后,得到下一状态'''
#u,d,l,r,n = -6,+6,-1,+1,0
if action == 'u' and state // self.MAZE_C != 0: # 除首行外,向上-MAZE_C
next_state = state - self.MAZE_C
elif action == 'd' and state // self.MAZE_C != self.MAZE_R - 1: # 除末行外,向下+MAZE_C
next_state = state + self.MAZE_C
elif action == 'l' and state % self.MAZE_C != 0: # 除首列外,向左-1
next_state = state - 1
elif action == 'r' and state % self.MAZE_C != self.MAZE_C - 1: # 除末列外,向右+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 i in range(episode):
current_state = self.states[0] if env is not None: # 若提供了环境,则重置之!
env.move_agent_to(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 next_state not in self.hell_states: # 非陷阱,则往前;否则待在原位
# current_state = next_state if env is not None: # 若提供了环境,则更新之!
env.move_agent_to(current_state)
print(i)
print('\nok') def test(self):
'''测试agent是否已具有智能'''
count = 0
current_state = self.states[0]
while current_state != self.states[-1]:
current_action = self.choose_action(current_state, 1.) # 1., 100%贪婪
next_state = self.get_next_state(current_state, current_action)
current_state = next_state
count += 1 if count > self.MAZE_R * self.MAZE_C: # 没有在36步之内走出迷宫,则
return False # 无智能 return True # 有智能 def play(self, env=None, step_time=0.5):
'''玩游戏,使用策略'''
assert env != None, 'Env must be not None!' if not self.test(): # 若尚无智能,则
if pathlib.Path("q_table.pickle").exists():
self.load_policy()
else:
print("I need to learn before playing this game.")
self.learn(env, episode=1000, epsilon=0.5)
self.save_policy() print('Agent is playing...')
current_state = self.states[0]
env.move_agent_to(current_state, step_time)
while current_state != self.states[-1]:
current_action = self.choose_action(current_state, 1.) # 1., 100%贪婪
next_state = self.get_next_state(current_state, current_action)
current_state = next_state
env.move_agent_to(current_state, step_time)
print('\nCongratulations, Agent got it!') if __name__ == '__main__':
env = Maze() # 环境
agent = Agent() # 个体(智能体)
agent.learn(env, episode=1000, epsilon=0.6) # 先学习
#agent.save_policy()
#agent.load_policy()
agent.play(env) # 再玩耍 #env.after(0, agent.learn, env, 1000, 0.8) # 先学
#env.after(0, agent.save_policy) # 保存所学
#env.after(0, agent.load_policy) # 导入所学
#env.after(0, agent.play, env) # 再玩
env.mainloop()
Just enjoy it!
【强化学习】python 实现 q-learning 迷宫通用模板的更多相关文章
- 深度强化学习(DQN-Deep Q Network)之应用-Flappy Bird
深度强化学习(DQN-Deep Q Network)之应用-Flappy Bird 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-fu ...
- 机器学习之强化学习概览(Machine Learning for Humans: Reinforcement Learning)
声明:本文翻译自Vishal Maini在Medium平台上发布的<Machine Learning for Humans>的教程的<Part 5: Reinforcement Le ...
- 深度强化学习(Deep Reinforcement Learning)入门:RL base & DQN-DDPG-A3C introduction
转自https://zhuanlan.zhihu.com/p/25239682 过去的一段时间在深度强化学习领域投入了不少精力,工作中也在应用DRL解决业务问题.子曰:温故而知新,在进一步深入研究和应 ...
- 【转】【强化学习】Deep Q Network(DQN)算法详解
原文地址:https://blog.csdn.net/qq_30615903/article/details/80744083 DQN(Deep Q-Learning)是将深度学习deeplearni ...
- [Reinforcement Learning] 强化学习介绍
随着AlphaGo和AlphaZero的出现,强化学习相关算法在这几年引起了学术界和工业界的重视.最近也翻了很多强化学习的资料,有时间了还是得自己动脑筋整理一下. 强化学习定义 先借用维基百科上对强化 ...
- Deep Learning专栏--强化学习之从 Policy Gradient 到 A3C(3)
在之前的强化学习文章里,我们讲到了经典的MDP模型来描述强化学习,其解法包括value iteration和policy iteration,这类经典解法基于已知的转移概率矩阵P,而在实际应用中,我们 ...
- (转) 深度强化学习综述:从AlphaGo背后的力量到学习资源分享(附论文)
本文转自:http://mp.weixin.qq.com/s/aAHbybdbs_GtY8OyU6h5WA 专题 | 深度强化学习综述:从AlphaGo背后的力量到学习资源分享(附论文) 原创 201 ...
- 强化学习论文(Scalable agent alignment via reward modeling: a research direction)
原文地址: https://arxiv.org/pdf/1811.07871.pdf ======================================================== ...
- 如何用简单例子讲解 Q - learning 的具体过程?
作者:牛阿链接:https://www.zhihu.com/question/26408259/answer/123230350来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
随机推荐
- Expo大作战(三十八)--expo sdk api之 FileSystem(文件操作系统)
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- ionic入门
ionic安装 Ionic开发是依赖于Nodejs环境的,所以在开发之前我们需要安装好Nodejs.下载安装:http://nodejs.org/安装完成之后打开PowerShell输入命令node ...
- Spring Boot 静态页面
spring boot项目只有src目录,没有webapp目录,会将静态访问(html/图片等)映射到其自动配置的静态目录,如下 /static /public /resources /META-IN ...
- 解决Linux终端乱码的两则例子
现象描述 我们先来说一下出现乱码的原因. 例子 先举个实际的例子,我们一般通过ssh远程到服务器上进行操作.当在终端上执行一些有输出的任务时,有可能会遇到乱码,特别是输出中有中文时. 比如,我登陆上o ...
- CentOS7下用firewall-cmd控制端口与端口转发
1.firewalld 守护进程 2.控制端口/服务 3.伪装IP 4.端口转发 实现目标:服务器A和服务器B都是内网互通的,但是只有服务器A是有外网然后现在做端口转发实现服务器B能使用服务器A的外网 ...
- 使用zip压缩文件夹方法
最近使用MapGis对.MPJ工程文件文件裁剪后,要对裁剪后的图形文件.ML,.MT,.MP,.MPJ文件打包,在网上找到7zip,Zlib的库,虽然都有源码,但是Zlib库中的使用没找到文件压缩的函 ...
- 3.3Python数据处理篇之Numpy系列(三)---数组的索引与切片
目录 (一)数组的索引与切片 1.说明: 2.实例: (二)多维数组的索引与切片 1.说明: 2.实例: 目录: 1.一维数组的索引与切片 2.多维数组的索引与切片 (一)数组的索引与切片 1.说明: ...
- 团队项目管理:Github项目误删恢复记录
参考: 准备更换git托管,如何迁移原git仓库 Github项目误删恢复记录 今天正常上线打卡,发现组织的线上Github仓库被误删了..本来是一场悲剧,所幸在本地的垃圾箱中翻出了还没有删除的本地仓 ...
- Alpha冲刺! Day7 - 砍柴
Alpha冲刺! Day7 - 砍柴 今日已完成 晨瑶:列了各模块目前的进度情况:确定了纯多媒体流星预览页的显示方式:给工具包函数列表新增了与服务器端的交互:玩华为软件云发现刚好可以试试它的测试,于是 ...
- bootstrap table使用及遇到的问题
本人前端菜鸟一枚,最近使用bootstrap table实现表格,记录一下以便日后翻阅,废话不多说,先看效果图: 1.首先说下要实现该效果需要添加的css样式及所需的js文件,具体下载地址就不粘贴了( ...