1. 问题概述

问题:MountainCarContinuous-v0

代码地址https://github.com/openai/gym/blob/master/gym/envs/classic_control/continuous_mountain_car.py

细节:动力不足的汽车必须爬上一维小山才能到达目标。 MountainCarContinuous-v0与MountainCar-v0不同,动作(应用的引擎力)允许是连续值。

目标位于汽车右侧的山顶上。 如果汽车到达或超出,则剧集终止。

在左侧,还有另一座山。 攀登这座山丘可以用来获得潜在的能量,并朝着目标加速。 在这第二座山顶上,汽车不能超过等于-1的位置,好像有一堵墙。 达到此限制不会产生惩罚(可能在更具挑战性的版本中)[1].

类型:连续控制

2. 环境

2.1 Observation & state

textObservation Min Max
0 Position -1.2 0.6
1 Velocity -0.07 0.07

请注意,速度受到限制以便于探索,但在更具挑战性的版本中可能会放宽此约束。

注意:Observation是 state的函数,二者有时相同,有时不同,在此例中,二者是一样的,在 Pendulum-v0中,Observation是state的函数。

2.2 Actions

n Action
0 将车推向左侧(负值)或向右侧(正值)

2.3 Reward

奖励为到达右侧山丘目标的100,减去从开始到目标的动作平方总和。这个奖励函数提出了一个探索挑战,因为如果代理人没有尽快到达目标,它将会发现最好不要移动,并且不再找到目标。

请注意,对于大多数已发表的作品而言,这种奖励是不寻常的,其目标是尽可能快地达到目标,因此有利于爆炸战略。

更多的奖励函数形式查看这个Leaderboard

2.4 初始状态

位于-0.6和-0.4之间,无速度。

2.5 终止状态- Episode Termination

位置等于0.5(此值可能被调整)。 可以在更具挑战性的版本中添加对速度的约束。

添加最大步数可能是个好主意。

2.6 Solved Requirements

获得超过90的奖励。此值可能会被调整。

3. 代码

3.1 导入lib

import math
import gym
from gym import spaces
from gym.utils import seeding
import numpy as np

3.2 定义Continuous_MountainCarEnv

class Continuous_MountainCarEnv(gym.Env):
metadata = {
'render.modes': ['human', 'rgb_array'],
'video.frames_per_second': 30
}

3.2.1 定义__init__(self)函数

def __init__(self):
self.min_action = -1.0 # 最小动作值
self.max_action = 1.0 # 最大动作值
self.min_position = -1.2 # 最低位置
self.max_position = 0.6 # 最高位置
self.max_speed = 0.07 # 最大速度
self.goal_position = 0.45 # was 0.5 in gym, 0.45 in Arnaud de Broissia's version
self.power = 0.0015 self.low_state = np.array([self.min_position, -self.max_speed]) # [-1.2, -0.07]
self.high_state = np.array([self.max_position, self.max_speed]) # [0.6, 0.07] self.viewer = None
# 声明observation space和action space的上下限
self.action_space = spaces.Box(low=self.min_action, high=self.max_action, shape=(1,))
# (low = 1.0, high = 1.0)
self.observation_space = spaces.Box(low=self.low_state, high=self.high_state)
# (low = -1.2, high = 0.6 ) self.seed()
self.reset()

3.2.2 定义随机种子函数seed(self, seed=None)

    def seed(self, seed=None):
self.np_random, seed = seeding.np_random(seed)
return [seed]

3.2.3 定义step(self, action)函数

step()函数

该函数在仿真器中扮演物理引擎的角色。其输入是动作action输出是:下一步状态,立即回报,是否终止,调试项。该函数描述了 智能体与环境交互的所有信息,是环境文件中最重要的函数。在该函数中, 一般利用智能体的运动学模型和动力学模型计算下一步的状态和立即回报,并判断是否达到终止状态

    def step(self, action):

  1.    position = self.state[0]
2. velocity = self.state[1]
# position, velocity = self.state
3. force = min(max(action[0], -1.0), 1.0) 4. velocity += force*self.power - 0.0025 * math.cos(3*position)
5. if (velocity > self.max_speed): velocity = self.max_speed
6. if (velocity < -self.max_speed): velocity = -self.max_speed
7. position += velocity
8. if (position > self.max_position): position = self.max_position
9. if (position < self.min_position): position = self.min_position
10. if (position==self.min_position and velocity<0): velocity = 0 11. done = bool(position >= self.goal_position) 12. reward = 0
13. if done:
14. reward = 100.0
15. reward-= math.pow(action[0],2)*0.1 16. self.state = np.array([position, velocity])
17. return self.state, reward, done, {}
  1. 初始化位置状态

  2. 初始化速度状态

  3. 引擎力:内层的max(action[0], -1.0)确保动作值不低于下界,即 - 1.0,

    外层的min(max(action[0], -1.0), 1.0)确保动作值不高于上界,即 1.0

  4. 计算速度:注意是速度累加的,这是微分的概念,把连续过程离散成很小的片段以进行近似

  5. 判断当前速度是否大于最大速度:如果是,将当前速度设定为最大速度

  6. 判断当前速度是否小于最小速度:如果是,将当前速度设定为最小速度

  7. 计算位置

  8. 判断当前位置是否高于最高位置:如果是,将当前位置设定为最高位置

  9. 判断当前位置是否低于最低位置:如果是,将当前位置设定为最低位置

  10. 如果当前位置是最低位置速度小于 0 :将速度设为0

  11. 判断布尔类型的,返回True或者False

  12. 初始化 reward = 0

  13. 如果当前位置高于目标位置,

  14. 给予 agent 值为100的reward

  15. 这是执行动作之后得到的新的状态

  16. step()

    函数返回下一时刻的观测,回报,是否终止,调试项

    MountainCarContinuous-v0

11-15 这几行代码的意思是:每执行一个step,就会检查看自己是否越过了右边的山峰,据此来给done赋值,如果小车没有越过右边的山峰,即 done=False,则在这一个step, reward将会记为,也就是这一个时间步我们耗费了多少能量,我们当然不希望耗油太多。如果小车越过右边的山峰,即 done=True,这一个step就会马上得到 的奖励。


3.2.4 定义reset()函数:

在强化学习算法中,智能体需要一次次地尝试,累积经验,然后从经验中学到好的动作。一次尝试我们称之为一条轨迹或一个episode. 每次尝试都要到达终止状态. 一次尝试结束后,智能体需要从头开始,这就需要智能体具有重新初始化的功能。函数reset()就是这个作用, agent与环境交互前调用该函数,确定agent的初始状态以及其他可能的一些初始化设置。此例中在每个episode开始时,position初始化为[-0.6,-0.4]之间的一个任意状态,速度初始化为0.

    def reset(self):
self.state = np.array([self.np_random.uniform(low=-0.6, high=-0.4), 0])
return np.array(self.state)

3.2.5 定义_height(self, xs)函数:

此函数用于下面的render()函数用来构建图像引擎

    def _height(self, xs):
return np.sin(3 * xs)*.45+.55

3.2.6 定义render(self, mode='human')函数

render()函数是图像引擎,就是人机交互界面,进行动画演示,一个仿真环境必不可少的两部分 是物理引擎和图像引擎。物理引擎模拟环境中物体的运动规律;图像引擎用来显示环境中的物体图像。

    def render(self, mode='human'):
screen_width = 600
screen_height = 400 world_width = self.max_position - self.min_position
scale = screen_width/world_width
carwidth=40
carheight=20 if self.viewer is None:
from gym.envs.classic_control import rendering
self.viewer = rendering.Viewer(screen_width, screen_height)
xs = np.linspace(self.min_position, self.max_position, 100)
ys = self._height(xs)
xys = list(zip((xs-self.min_position)*scale, ys*scale)) self.track = rendering.make_polyline(xys)
self.track.set_linewidth(4)
self.viewer.add_geom(self.track) clearance = 10 l,r,t,b = -carwidth/2, carwidth/2, carheight, 0
car = rendering.FilledPolygon([(l,b), (l,t), (r,t), (r,b)])
car.add_attr(rendering.Transform(translation=(0, clearance)))
self.cartrans = rendering.Transform()
car.add_attr(self.cartrans)
self.viewer.add_geom(car)
frontwheel = rendering.make_circle(carheight/2.5)
frontwheel.set_color(.5, .5, .5)
frontwheel.add_attr(rendering.Transform(translation=(carwidth/4,clearance)))
frontwheel.add_attr(self.cartrans)
self.viewer.add_geom(frontwheel)
backwheel = rendering.make_circle(carheight/2.5)
backwheel.add_attr(rendering.Transform(translation=(-carwidth/4,clearance)))
backwheel.add_attr(self.cartrans)
backwheel.set_color(.5, .5, .5)
self.viewer.add_geom(backwheel)
flagx = (self.goal_position-self.min_position)*scale
flagy1 = self._height(self.goal_position)*scale
flagy2 = flagy1 + 50
flagpole = rendering.Line((flagx, flagy1), (flagx, flagy2))
self.viewer.add_geom(flagpole)
flag = rendering.FilledPolygon([(flagx, flagy2), (flagx, flagy2-10),
(flagx+25, flagy2-5)])
flag.set_color(.8,.8,0)
self.viewer.add_geom(flag) pos = self.state[0]
self.cartrans.set_translation((pos-self.min_position)*scale, self._height(pos)*scale)
self.cartrans.set_rotation(math.cos(3 * pos)) return self.viewer.render(return_rgb_array = mode=='rgb_array')

强化学习算法可以不用图像引擎,这里我们不做解释了。

3.2.7 定义close(self)函数

    def close(self):
if self.viewer:
self.viewer.close()
self.viewer = None

4. 运行

4.1 完整代码:continuous_mountain_car.py

"""
MountainCarContinuous-v1
@author: Olivier Sigaud
A merge between two sources:
* Adaptation of the MountainCar Environment from the "FAReinforcement" library
of Jose Antonio Martin H. (version 1.0), adapted by 'Tom Schaul, tom@idsia.ch'
and then modified by Arnaud de Broissia
* the OpenAI/gym MountainCar environment
itself from
http://incompleteideas.net/sutton/MountainCar/MountainCar1.cp
permalink: https://perma.cc/6Z2N-PFWC
""" import math import numpy as np import gym
from gym import spaces
from gym.utils import seeding class ContinuousMountainCarEnv(gym.Env):
"""
Description:
The agent (a car) is started at the bottom of a valley. For any given
state the agent may choose to accelerate to the left, right or cease
any acceleration.
Observation:
Type: Box(2)
Num Observation Min Max
0 Car Position -1.2 0.6
1 Car Velocity -0.07 0.07
Actions:
Type: Box(1)
Num Action Min Max
0 the power coef -1.0 1.0
Note: actual driving force is calculated by multiplying the power coef by power (0.0015)
Reward:
Reward of 100 is awarded if the agent reached the flag (position = 0.45) on top of the mountain.
Reward is decrease based on amount of energy consumed each step.
Starting State:
The position of the car is assigned a uniform random value in
[-0.6 , -0.4].
The starting velocity of the car is always assigned to 0.
Episode Termination:
The car position is more than 0.45
Episode length is greater than 200
""" metadata = {"render.modes": ["human", "rgb_array"], "video.frames_per_second": 30} def __init__(self, goal_velocity=0):
self.min_action = -1.0
self.max_action = 1.0
self.min_position = -1.2
self.max_position = 0.6
self.max_speed = 0.07
self.goal_position = (
0.45 # was 0.5 in gym, 0.45 in Arnaud de Broissia's version
)
self.goal_velocity = goal_velocity
self.power = 0.0015 self.low_state = np.array(
[self.min_position, -self.max_speed], dtype=np.float32
)
self.high_state = np.array(
[self.max_position, self.max_speed], dtype=np.float32
) self.viewer = None self.action_space = spaces.Box(
low=self.min_action, high=self.max_action, shape=(1,), dtype=np.float32
)
self.observation_space = spaces.Box(
low=self.low_state, high=self.high_state, dtype=np.float32
) self.seed() def seed(self, seed=None):
self.np_random, seed = seeding.np_random(seed)
return [seed] def step(self, action): position = self.state[0]
velocity = self.state[1]
force = min(max(action[0], self.min_action), self.max_action) velocity += force * self.power - 0.0025 * math.cos(3 * position)
if velocity > self.max_speed:
velocity = self.max_speed
if velocity < -self.max_speed:
velocity = -self.max_speed
position += velocity
if position > self.max_position:
position = self.max_position
if position < self.min_position:
position = self.min_position
if position == self.min_position and velocity < 0:
velocity = 0 # Convert a possible numpy bool to a Python bool.
done = bool(position >= self.goal_position and velocity >= self.goal_velocity) reward = 0
if done:
reward = 100.0
reward -= math.pow(action[0], 2) * 0.1 self.state = np.array([position, velocity], dtype=np.float32)
return self.state, reward, done, {} def reset(self):
self.state = np.array([self.np_random.uniform(low=-0.6, high=-0.4), 0])
return np.array(self.state, dtype=np.float32) def _height(self, xs):
return np.sin(3 * xs) * 0.45 + 0.55 def render(self, mode="human"):
screen_width = 600
screen_height = 400 world_width = self.max_position - self.min_position
scale = screen_width / world_width
carwidth = 40
carheight = 20 if self.viewer is None:
from gym.envs.classic_control import rendering self.viewer = rendering.Viewer(screen_width, screen_height)
xs = np.linspace(self.min_position, self.max_position, 100)
ys = self._height(xs)
xys = list(zip((xs - self.min_position) * scale, ys * scale)) self.track = rendering.make_polyline(xys)
self.track.set_linewidth(4)
self.viewer.add_geom(self.track) clearance = 10 l, r, t, b = -carwidth / 2, carwidth / 2, carheight, 0
car = rendering.FilledPolygon([(l, b), (l, t), (r, t), (r, b)])
car.add_attr(rendering.Transform(translation=(0, clearance)))
self.cartrans = rendering.Transform()
car.add_attr(self.cartrans)
self.viewer.add_geom(car)
frontwheel = rendering.make_circle(carheight / 2.5)
frontwheel.set_color(0.5, 0.5, 0.5)
frontwheel.add_attr(
rendering.Transform(translation=(carwidth / 4, clearance))
)
frontwheel.add_attr(self.cartrans)
self.viewer.add_geom(frontwheel)
backwheel = rendering.make_circle(carheight / 2.5)
backwheel.add_attr(
rendering.Transform(translation=(-carwidth / 4, clearance))
)
backwheel.add_attr(self.cartrans)
backwheel.set_color(0.5, 0.5, 0.5)
self.viewer.add_geom(backwheel)
flagx = (self.goal_position - self.min_position) * scale
flagy1 = self._height(self.goal_position) * scale
flagy2 = flagy1 + 50
flagpole = rendering.Line((flagx, flagy1), (flagx, flagy2))
self.viewer.add_geom(flagpole)
flag = rendering.FilledPolygon(
[(flagx, flagy2), (flagx, flagy2 - 10), (flagx + 25, flagy2 - 5)]
)
flag.set_color(0.8, 0.8, 0)
self.viewer.add_geom(flag) pos = self.state[0]
self.cartrans.set_translation(
(pos - self.min_position) * scale, self._height(pos) * scale
)
self.cartrans.set_rotation(math.cos(3 * pos)) return self.viewer.render(return_rgb_array=mode == "rgb_array") def close(self):
if self.viewer:
self.viewer.close()
self.viewer = None

4.2 注册环境

第一步:将我们自己的环境文件(我创建的文件名为continuous_mountain_car.py)拷贝到你的gym安装目录./gym/gym/envs/classic_control文件夹中。(拷贝在这个文件夹中因为要使用rendering模块。当然,也有其他办法。该方法不唯一)

第二步:打开该文件夹(第一步中的文件夹)下的__init__.py文件,在文件末尾加入语句:

from gym.envs.classic_control.continuous_mountain_car import ContinuousMountainCarEnv

第三步:进入文件夹你的gym安装目录./gym/gym/envs,打开该文件夹下的__init__.py文件,添加代码:

register(

id='MountainCarContinuous-v1',

entry_point='gym.envs.classic_control:GridEnv'

)

"""
第一个参数id就是你调用gym.make(‘id’)时的id, 这个id你可以随便选取,我取的,名字是MountainCarContinuous-v1。
第二个参数就是函数路口。
"""

经过以上三步,就完成了注册。

4.3 创建运行代码:MountainCarContinuous.py

创建这个运行代码后直接运行即可。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Toolby: PyCharm import gym env = gym.make('MountainCarContinuous-v1')
env = env.unwrapped total_steps = 0 for i_episode in range(10): observation = env.reset()
ep_r = 0
while True:
env.render() action = env.action_space.sample() observation_, reward, done, info = env.step(action) position, velocity = observation_ # 车开得越高 reward 越大
reward = abs(position - (-0.5)) ep_r += reward
if done:
get = '| Get' if observation_[0] >= env.unwrapped.goal_position else '| ----'
print('Epi: ', i_episode,
get,
'| Ep_r: ', round(ep_r, 4)) break observation = observation
total_steps += 1

五:参考

  1. https://github.com/openai/gym/wiki/MountainCarContinuous-v0
  2. https://github.com/openai/gym/blob/master/gym/envs/classic_control/continuous_mountain_car.py
  3. https://applenob.github.io/mountain_car.html
  4. https://blog.csdn.net/u013745804/article/details/78403912
  5. 强化学习实践二 理解gym的建模思想

强化学习之MountainCarContinuous(注册自己的gym环境)的更多相关文章

  1. 【强化学习】百度云BCC openai gym 环境配置

    openai gym是RL算法的测试床.为了直观和便于调试,我们需要可视化界面.然而远程服务器使用openGL的问题比较棘手,这篇博客记录在百度云BCC上配置openai gym环境的注意事项. 按照 ...

  2. 强化学习实战 | 自定义Gym环境

    新手的第一个强化学习示例一般都从Open Gym开始.在这些示例中,我们不断地向环境施加动作,并得到观测和奖励,这也是Gym Env的基本用法: state, reward, done, info = ...

  3. 【转载】 强化学习(十一) Prioritized Replay DQN

    原文地址: https://www.cnblogs.com/pinard/p/9797695.html ------------------------------------------------ ...

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

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

  5. 深度强化学习day01初探强化学习

    深度强化学习 基本概念 强化学习 强化学习(Reinforcement Learning)是机器学习的一个重要的分支,主要用来解决连续决策的问题.强化学习可以在复杂的.不确定的环境中学习如何实现我们设 ...

  6. Flink + 强化学习 搭建实时推荐系统

    如今的推荐系统,对于实时性的要求越来越高,实时推荐的流程大致可以概括为这样: 推荐系统对于用户的请求产生推荐,用户对推荐结果作出反馈 (购买/点击/离开等等),推荐系统再根据用户反馈作出新的推荐.这个 ...

  7. 强化学习实战 | 自定义Gym环境之井字棋

    在文章 强化学习实战 | 自定义Gym环境 中 ,我们了解了一个简单的环境应该如何定义,并使用 print 简单地呈现了环境.在本文中,我们将学习自定义一个稍微复杂一点的环境--井字棋.回想一下井字棋 ...

  8. 强化学习实战 | 自定义Gym环境之扫雷

    开始之前 先考虑几个问题: Q1:如何展开无雷区? Q2:如何计算格子的提示数? Q3:如何表示扫雷游戏的状态? A1:可以使用递归函数,或是堆栈. A2:一般的做法是,需要打开某格子时,再去统计周围 ...

  9. 强化学习 平台 openAI 的 gym 安装 (Ubuntu环境下如何安装Python的gym模块)

    openAI 公司给出了一个集成较多环境的强化学习平台  gym , 本篇博客主要是讲它怎么安装. openAI公司的主页: https://www.openai.com/systems/ 从主页上我 ...

随机推荐

  1. 使用寄存器点亮LED——2

    1. 项目:使用stm32寄存器点亮LED, 分别点亮红.绿.蓝3个灯. 2. 步骤 先新建个文件夹保存项目 再新建项目 将startup_stm32f10x_hd.s拷贝到该文件夹下 新建main. ...

  2. zuul过滤器filter 的编写

    通过上一节(zuul的各种配置)的学习,我们学会了zuul路由的各种配置,这一节我们来实现一下zuul的过滤器功能.那么为什么需要用到zuul的过滤器呢?我们知道zuul是我们实现外部系统统一访问的入 ...

  3. centOs7.6安装 mysql-8.0.27

    1.下载mysql 2.连接服务器 3.通过 rpm -qa | grep mariadb 命令查看 mariadb 的安装包 4.通过 rpm -e mariadb-libs-5.5.68-1.el ...

  4. Noip模拟80 2021.10.18

    预计得分:5 实际得分:140?????????????? T1 邻面合并 我考场上没切掉的大水题....(证明我旁边的cty切掉了,并觉得很水) 然而贪心拿了六十,离谱,成功做到上一篇博客说的有勇气 ...

  5. stm32中的串口通信你了解多少

    在基础实验成功的基础上,对串口的调试方法进行实践.硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中. b) 初始化函数定义: void USART_Confi ...

  6. 硬件工程师必须掌握的PCB叠层设计内容

    总的来说叠层设计主要要遵从两个规矩: 1. 每个走线层都必须有一个邻近的参考层(电源或地层); 2. 邻近的主电源层和地层要保持最小间距,以提供较大的耦合电容; 下面列出从两层板到八层板的叠层来进行示 ...

  7. 种类并查集(维护敌人的敌人是朋友)、并行-poj1182-食物链 笔记

    题意 输入若干组数据,代表着不同动物在食物链的位置(A,B,C),要求出在输入的过程中有多少组数据会与之前矛盾. 思路(借鉴挑战程序设计竞赛) 这题是学并查集时的题,所以用了并查集. 一开始我想的是, ...

  8. bash执行顺序:alias --> function --> builtin --> program

    linux bash的执行顺序如下所示: 先 alias --> function --> builtin --> program 后 验证过程: 1,在bash shell中有内置 ...

  9. usb设备无法识别

    之前用飞线用旧板子飞线连接了一个wifi模块到usb0口上,调试ok的,现在新设计的板子回来了,wifi模块是连接在usb2口上的,系统起来后发现wlan0不存在,用lsusb查看wifi模块的usb ...

  10. hdu 2830 Matrix Swapping II(额,,排序?)

    题意: N*M的矩阵,每个格中不是0就是1. 可以任意交换某两列.最后得到一个新矩阵. 问可以得到的最大的子矩形面积是多少(这个子矩形必须全是1). 思路: 先统计,a[i][j]记录从第i行第j列格 ...