强化学习:带起始探索的每次访问同策回合更新算法求解机器人找金币问题

2023-11-18

1.问题描述

在这里插入图片描述
在这里插入图片描述

2. 环境建模

在这里插入图片描述

3. 游戏环境类roadenv()设计

class roadenv():
    def __init__(self,epsilon=0.5,gamma=0.8):
        # 状态空间-动作空间
        self.states = [1, 2, 3, 4, 5, 6, 7, 8]
        self.actions = ['n', 'e', 's', 'w']
        # 回报函数
        self.rewards = dict()
        self.rewards['1_s'] = -1
        self.rewards['3_s'] = 1
        self.rewards['5_s'] = -1
        # 状态转移概率
        self.t = dict()
        self.t['1_s'] = 6
        self.t['1_e'] = 2
        self.t['2_w'] = 1
        self.t['2_e'] = 3
        self.t['3_s'] = 7
        self.t['3_w'] = 2
        self.t['3_e'] = 4
        self.t['4_w'] = 3
        self.t['4_e'] = 5
        self.t['5_s'] = 8
        self.t['5_w'] = 4
        # 当前状态
        self.state = 1
        # 动作价值函数
        self.q = np.zeros(((len(self.states) + 1),len(self.actions)))
        self.qn = np.zeros(((len(self.states) + 1),len(self.actions)))
        self.policy = np.zeros(len(self.states) + 1)
        self.epsilon = epsilon
        self.gamma = gamma

    def reset(self):
        state = self.states[int(random.random()*len(self.states))]
        self.state = state
        return self.state

    def step(self, action):
        state = self.state
        if (state == 6) or (state == 8):
            return state,-1,True,{}
        elif state == 7:
            return state,1,True,{}
        key = '%d_%s'%(state,action)
        if key in self.t:
            next_state = self.t[key]
        else:
            next_state = state
        self.state = next_state
        is_terminal = False
        if (next_state == 6)or(next_state == 7) or(next_state == 8):
            is_terminal = True
        if key not in self.rewards:
            r = 0
        else:
            r = self.rewards[key]
        return next_state,r,is_terminal,{}

4.MonteCarlo采样轨迹

# 下面是蒙特卡洛方法(每次访问异策回合更新)的采样
    def gen_random_sample(self,num=100):
        # num:采样次数
        state_sample  = []
        action_sample = []
        reward_sample = []
        for i in range(num):
            # 用来存储临时的(s,a,r)
            s_temp = []
            a_temp = []
            r_temp = []
            # 初始化每个回合的开始状态(试探性出发假设)
            s = self.states[int(random.random()*(len(self.states)-0))]
            # 结束标记
            flag = False
            while flag == False:
                # 每回合开始随机产生动作
                a = self.actions[int(random.random()*(len(self.actions)-0))]
                # 在当前(s)状态下采样a
                self.state = s
                next_s,r,flag,_ = self.step(a)
                s_temp.append(s)
                a_temp.append(a)
                r_temp.append(r)
                s = next_s
            state_sample.append(s_temp)
            action_sample.append(a_temp)
            reward_sample.append(r_temp)
        return state_sample,action_sample,reward_sample

5.决策过程

采用贪心策略( ε \varepsilon ε-greedy策略)采样:

# 决策过程(epsiolon-greedy)
    def decide(self,state):
        if np.random.rand()<self.epsilon:
            return self.actions[int(random.random()*len(self.actions))]
        else:
            return self.actions[int(self.policy[state])]

6.策略评估与策略改进

# 蒙特卡洛评估动作价值函数q(s,a)
    def evaluate_q(self,state_sample, action_sample, reward_sample):
        # state_sample,action_sample,reward_sample都是一维数组
        G = 0 # 初始化回报
        action_map = {'n':0, 'e':1, 's':2, 'w':3}
        for t in range(len(state_sample)-1,-1,-1):
            s_t = state_sample[t]
            # if s_t >= 8:
            #     print("s_t>=8,s_t:{}".format(s_t))
            r_t = reward_sample[t]
            a_t = action_sample[t]
            a_t_index = action_map[a_t]
            # 下面是MonteCarlo更新
            G = self.gamma*G + r_t
            self.qn[s_t,a_t_index] += 1
            self.q[s_t,a_t_index] += (G - self.q[s_t,a_t_index])/self.qn[s_t,a_t_index]
            # 策略改进
    def impove_policy(self):
        for state in range(len(self.states)):
            a_s_index = np.argmax(self.q[state])
            self.policy[state] = a_s_index

7. 学习算法

# 同策回合更新(学习)过程-给出决策policy
    def learn(self,epsiodes=100):
        epsiode_array = []
        reward_array = []
        for epsiode in range(epsiodes):
            s_sample,a_sample,r_sample = [],[],[]
            # 下面是试探性出发假设
            s = self.states[int(len(self.states)*random.random())]
            a = self.actions[int(len(self.actions)*random.random())]
            flag = False # 结束标记
            # 下面将用贪心策略产生轨迹
            while flag == False:
                # 当前状态设置为s
                self.state = s
                # 设置转移
                next_s,r,flag,_ = self.step(a)
                # 贪心策略生成新的策略
                a = self.decide(next_s)
                s = next_s
                # 保存轨迹
                s_sample.append(next_s)
                a_sample.append(a)
                r_sample.append(r)
            # 策略评估
            self.evaluate_q(s_sample,a_sample,r_sample)
            # 策略改进
            self.impove_policy()
            reward_array.append(np.sum(r_sample))
        # 下面将策略进行转码
        policy_symbol = []
        for state in self.states:
            policy_symbol.append(self.actions[int(self.policy[int(state)])])
        return policy_symbol,reward_array

8.主函数

if __name__ == "__main__":
    print("------下面是同策回合更新---------")
    game = roadenv(epsilon=0.1,gamma=0.8)
    game.reset()
    policy,reward_array = game.learn(epsiodes=100)
    print(policy)
    plt.plot(reward_array)
    plt.waitforbuttonpress()

9.结果

------下面是同策回合更新---------
['e', 'e', 's', 'w', 'w', 'n', 'n', 'n']

在这里插入图片描述

发现最好的奖励是1.0,正好就是直接从7号点出去的路径。

10.附录(完整代码)

import numpy as np
import random
import matplotlib.pyplot as plt
class roadenv():
    def __init__(self,epsilon=0.5,gamma=0.8):
        # 状态空间-动作空间
        self.states = [1, 2, 3, 4, 5, 6, 7, 8]
        self.actions = ['n', 'e', 's', 'w']
        # 回报函数
        self.rewards = dict()
        self.rewards['1_s'] = -1
        self.rewards['3_s'] = 1
        self.rewards['5_s'] = -1
        # 状态转移概率
        self.t = dict()
        self.t['1_s'] = 6
        self.t['1_e'] = 2
        self.t['2_w'] = 1
        self.t['2_e'] = 3
        self.t['3_s'] = 7
        self.t['3_w'] = 2
        self.t['3_e'] = 4
        self.t['4_w'] = 3
        self.t['4_e'] = 5
        self.t['5_s'] = 8
        self.t['5_w'] = 4
        # 当前状态
        self.state = 1
        # 动作价值函数
        self.q = np.zeros(((len(self.states) + 1),len(self.actions)))
        self.qn = np.zeros(((len(self.states) + 1),len(self.actions)))
        self.policy = np.zeros(len(self.states) + 1)
        self.epsilon = epsilon
        self.gamma = gamma

    def reset(self):
        state = self.states[int(random.random()*len(self.states))]
        self.state = state
        return self.state

    def step(self, action):
        state = self.state
        if (state == 6) or (state == 8):
            return state,-1,True,{}
        elif state == 7:
            return state,1,True,{}
        key = '%d_%s'%(state,action)
        if key in self.t:
            next_state = self.t[key]
        else:
            next_state = state
        self.state = next_state
        is_terminal = False
        if (next_state == 6)or(next_state == 7) or(next_state == 8):
            is_terminal = True
        if key not in self.rewards:
            r = 0
        else:
            r = self.rewards[key]
        return next_state,r,is_terminal,{}

    # 下面是蒙特卡洛方法(每次访问异策回合更新)的采样
    def gen_random_sample(self,num=100):
        # num:采样次数
        state_sample  = []
        action_sample = []
        reward_sample = []
        for i in range(num):
            # 用来存储临时的(s,a,r)
            s_temp = []
            a_temp = []
            r_temp = []
            # 初始化每个回合的开始状态(试探性出发假设)
            s = self.states[int(random.random()*(len(self.states)-0))]
            # 结束标记
            flag = False
            while flag == False:
                # 每回合开始随机产生动作
                a = self.actions[int(random.random()*(len(self.actions)-0))]
                # 在当前(s)状态下采样a
                self.state = s
                next_s,r,flag,_ = self.step(a)
                s_temp.append(s)
                a_temp.append(a)
                r_temp.append(r)
                s = next_s
            state_sample.append(s_temp)
            action_sample.append(a_temp)
            reward_sample.append(r_temp)
        return state_sample,action_sample,reward_sample

    # 蒙特卡洛评估价值函数v
    def evaluate_v(self,state_sample,action_sample,reward_sample):
        # 初始化v[s],n[s] = 0
        vfunc = dict()
        nfunc = dict()
        for s in self.states:
            vfunc[s] = 0.0
            nfunc[s] = 0.0
        for epsiode in range(len(state_sample)):
            G = 0
            # 初始化一个G_array用于后面
            G_array = []
            for i in range(len(state_sample[epsiode])):
                G_array.append(0)
            # 从最后一个开始G
            for step in range(len(state_sample[epsiode])-1,-1,-1):
                G = self.gamma*G + reward_sample[epsiode][step]
                G_array[step] = G
                s = state_sample[epsiode][step]
                nfunc[s] += 1
                vfunc[s] += (G_array[step] - vfunc[s])/nfunc[s]
        print("价值函数{}".format(vfunc))
        return vfunc

    # 蒙特卡洛评估动作价值函数q(s,a)
    def evaluate_q(self,state_sample, action_sample, reward_sample):
        # state_sample,action_sample,reward_sample都是一维数组
        G = 0 # 初始化回报
        action_map = {'n':0, 'e':1, 's':2, 'w':3}
        for t in range(len(state_sample)-1,-1,-1):
            s_t = state_sample[t]
            # if s_t >= 8:
            #     print("s_t>=8,s_t:{}".format(s_t))
            r_t = reward_sample[t]
            a_t = action_sample[t]
            a_t_index = action_map[a_t]
            # 下面是MonteCarlo更新
            G = self.gamma*G + r_t
            self.qn[s_t,a_t_index] += 1
            self.q[s_t,a_t_index] += (G - self.q[s_t,a_t_index])/self.qn[s_t,a_t_index]

    # 策略改进
    def impove_policy(self):
        for state in range(len(self.states)):
            a_s_index = np.argmax(self.q[state])
            self.policy[state] = a_s_index

    # 决策过程(epsiolon-greedy)
    def decide(self,state):
        if np.random.rand()<self.epsilon:
            return self.actions[int(random.random()*len(self.actions))]
        else:
            return self.actions[int(self.policy[state])]

    # 同策回合更新(学习)过程-给出决策policy
    def learn(self,epsiodes=100):
        epsiode_array = []
        reward_array = []
        for epsiode in range(epsiodes):
            s_sample,a_sample,r_sample = [],[],[]
            # 下面是试探性出发假设
            s = self.states[int(len(self.states)*random.random())]
            a = self.actions[int(len(self.actions)*random.random())]
            flag = False # 结束标记
            # 下面将用贪心策略产生轨迹
            while flag == False:
                # 当前状态设置为s
                self.state = s
                # 设置转移
                next_s,r,flag,_ = self.step(a)
                # 贪心策略生成新的策略
                a = self.decide(next_s)
                s = next_s
                # 保存轨迹
                s_sample.append(next_s)
                a_sample.append(a)
                r_sample.append(r)
            # 策略评估
            self.evaluate_q(s_sample,a_sample,r_sample)
            # 策略改进
            self.impove_policy()
            reward_array.append(np.sum(r_sample))
        # 下面将策略进行转码
        policy_symbol = []
        for state in self.states:
            policy_symbol.append(self.actions[int(self.policy[int(state)])])
        return policy_symbol,reward_array

# 下面是主函数
if __name__ == "__main__":
    # game = roadenv(epsilon=0.1)
    # game.reset()
    # game.state = 2
    # print("当前状态为:"+str(game.state))
    # next_state,r,is_terminal,_ = game.step('w')
    # print('现在状态为:{}'.format(next_state))
    # print("------下面开始测试蒙特卡洛采样--------")
    # state_sample,action_sample,reward_sample = game.gen_random_sample()
    # print("state_sample:{}".format(state_sample))
    # print("action_sample:{}".format(action_sample))
    # print("reward_sample:{}".format(reward_sample))
    # # print("------下面开始进行评估价值函数--------")
    # # vfunc = game.evaluate_v(state_sample,action_sample,reward_sample)
    print("------下面是同策回合更新---------")
    game = roadenv(epsilon=0.1,gamma=0.8)
    game.reset()
    policy,reward_array = game.learn(epsiodes=100)
    print(policy)
    plt.plot(reward_array)
    plt.waitforbuttonpress()

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

强化学习:带起始探索的每次访问同策回合更新算法求解机器人找金币问题 的相关文章

  • pandas Wide_to_long 后缀参数

    我对在 pandas 中使用 Wide to long 时的参数有疑问 有一个参数叫suffix我不明白 在文档中它说 后缀 str 默认 d 捕获所需后缀的正则表达式 d 捕获数字后缀 没有数字的后缀可以用否定字符类 D 指定 您还可以进
  • ca 证书 Mac OS X

    我需要在emacs 上安装offlineimap 和mu4e 问题是配置 当我运行 Offlineimap 时 我得到 OfflineIMAP 6 5 5 Licensed under the GNU GPL v2 v2 or any la
  • Pandas 连接问题:列重叠但未指定后缀

    我有以下数据框 print df a mukey DI PI 0 100000 35 14 1 1000005 44 14 2 1000006 44 14 3 1000007 43 13 4 1000008 43 13 print df b
  • 使用多级解决方案计算二维网格中的最近邻

    我有一个问题 在 x y 大小的网格中 我提供了一个点 并且我需要找到最近的邻居 在实践中 我试图在 pygame 中找到距离光标最近的点 该点跨越颜色距离阈值 计算如下 sqrt rgb1 0 rgb2 0 2 rgb1 1 rgb2 1
  • numpy:大量线段/点的快速规则间隔平均值

    我沿着一维线有许多 约 100 万个 不规则间隔的点 P 这些标记线段 这样 如果点是 0 x a x b x c x d 则线段从 0 gt x a x a gt x b x b gt x c x c gt x d 等 我还有每个段的 y
  • 通用详细视图 ProfileView 必须使用对象 pk 或 slug 调用

    我是 Django 2 0 的新手 在访问我的个人资料页面视图时收到此错误 它适用于像这样的网址path users
  • 在Python中以交互方式执行多行语句

    我是 Python 世界的新手 这是我用 Python 编写的第一个程序 我来自 R 世界 所以这对我来说有点不直观 当我执行时 In 15 import math import random random random math sqrt
  • 如何在Python代码中查找列号

    简短问题 当按上述方式调用函数时 我可以找到行号here https stackoverflow com questions 3056048 filename and line number of python script 同样 如何找到
  • 张量流和线程

    下面是来自 Tensorflow 网站的简单 mnist 教程 即单层 softmax 我尝试通过多线程训练步骤对其进行扩展 from tensorflow examples tutorials mnist import input dat
  • 返回上个月的日期时间对象

    如果 timedelta 在它的构造函数中有一个月份参数就好了 那么最简单的方法是什么 EDIT 正如下面指出的那样 我并没有认真考虑这一点 我真正想要的是上个月的任何一天 因为最终我只会获取年份和月份 因此 给定一个日期时间对象 返回的最
  • Pandas:将 pytz.FixedOffset 应用于系列

    我有一个带有timestamp列看起来像这样 0 2020 01 26 05 00 00 08 00 1 2020 01 26 06 00 00 08 00 Name timestamp dtype datetime64 ns pytz F
  • PyArmor - 打包为一个可执行文件

    当我执行此命令时 您好 使用 PyArmor pyarmor pack main py 它将它打包到一个名为的文件夹中dist里面包含我的 exe 以及许多 Python 扩展文件 据我所知 PyArmor 使用 PyInstaller 来
  • 在seaborn中对箱线图x轴进行排序

    我的数据框round data看起来像这样 error username task path 0 0 02 n49vq14uhvy93i5uw33tf7s1ei07vngozrzlsr6q6cnh8w 39 png 1 0 10 n49vq
  • python dicttoxml 多次使用相同的键

    我正在尝试做如下所示的 xml
  • 在 scipy 中创建新的发行版

    我试图根据我拥有的一些数据创建一个分布 然后从该分布中随机抽取 这是我所拥有的 from scipy import stats import numpy def getDistribution data kernel stats gauss
  • Python 导入非常慢 - Anaconda python 2.7

    我的 python import 语句变得非常慢 我使用 Anaconda 包在本地运行 python 2 7 导入模块后 我编写的代码运行得非常快 似乎只是导入需要很长时间 例如 我使用以下代码运行了一个 tester py 文件 imp
  • Python:无法使用 os.system() 打开文件

    我正在编写一个使用该应用程序的 Python 脚本pdftk http www pdflabs com tools pdftk the pdf toolkit 几次来执行某些操作 例如 我可以在 Windows 命令行 shell 中使用
  • 沿轴 0 重复 scipy csr 稀疏矩阵

    我想重复 scipy csr 稀疏矩阵的行 但是当我尝试调用 numpy 的重复方法时 它只是将稀疏矩阵视为对象 并且只会将其作为 ndarray 中的对象重复 我浏览了文档 但找不到任何实用程序来重复 scipy csr 稀疏矩阵的行 我
  • 如何更改matplotlib中双头注释的头大小?

    Below figure shows the plot of which arrow head is very small 我尝试了下面的代码 但它不起作用 它说 引发 AttributeError 未知属性 s k 属性错误 未知属性头宽
  • Python 中的字符串slugification

    我正在寻找 slugify 字符串的最佳方法 蛞蝓 是什么 https stackoverflow com questions 427102 in django what is a slug 我当前的解决方案基于这个食谱 http code

随机推荐

  • Python Web:Flask异步执行任务

    Flask 是 Python 中有名的轻量级同步 web 框架 在一些开发中 可能会遇到需要长时间处理的任务 此时就需要使用异步的方式来实现 让长时间任务在后台运行 先将本次请求的响应状态返回给前端 不让前端界面 卡顿 当异步任务处理好后
  • jQuery empty() vs remove()

    https stackoverflow com questions 3090662 jquery empty vs remove http www cnblogs com yeer archive 2009 06 10 1500682 ht
  • JavaSE复习笔记

    第一章 Java概述 一 计算机语言 机器语言 汇编语言 高级语言 二 跨平台原理 Java可以在一处开发到处运行 即在一类操作系统上开发的程序 可以在任何操作系统上运行 不同的操作系统有不同的JVM java是运行在JVM上 从而实现了跨
  • win7系统打开定位服务器地址,win7 定位服务器地址

    win7 定位服务器地址 内容精选 换一换 您可以通过云日志服务 查看访问七层共享型负载均衡请求的详细日志记录 分析负载均衡的响应状态码 快速定位异常的后端服务器 您已经创建了七层负载均衡 您已经开通了云日志服务 登录管理控制台 在管理控制
  • 函数式组件与类组件有何不同?

    与React类组件相比 React函数式组件究竟有何不同 在过去一段时间里 典型的回答是类组件提供了更多的特性 比如state 当有了Hooks后 答案就不再是这样了 或许你曾听过它们中的某一个在性能上的表现优于另一个 那是哪一个 很多此类
  • MultipartFile实现文件上传和下载(Springboot)

    MultipartFile是SpringMVC提供简化上传操作的工具类 在不使用框架之前 都是使用原生的HttpServletRequest来接收上传的数据 文件是以二进制流传递到后端的 然后需要我们自己转换为File类 使用了Multip
  • 计算机专业选修课怎么选比较好,大一选修课选什么好 大学选修课推荐

    大学之于高中最大的不同点除了越来越多的自由时间以外 大学有各种各样的选修课供我们选择 在专业课之余 还可以选择其他自己感兴趣的学科进行学习 同时也能给自己增加一项技能 大学热门选修课 1 职场礼仪 礼仪是永远不会过时的 它是一个人的修养素质
  • 语法6:raise - 触发异常

    目录 1 基础格式 2 raise 单独语句 3 raise class 4 raise instance 5 raise from 6 try raise 实现循环跳出
  • JDK的命令行工具——修改中

    目录 一 jps 虚拟机进程状况工具 二 jstat 虚拟机统计信息监视工具 三 jinfo java配置信息工具 四 jmap java内存映像工具 五 jhat 虚拟机堆转储快照分析工具 仅做了解即可 六 jstack java堆栈跟踪
  • 以太坊私有网络的设置与体验

    记录一下搭建一个以太坊私有网络环境的过程 方便以后的开发 我这里采用的是Geth客户端 在geth ethereum org网站上有详细的文档介绍 这里主要是按照官网的教程来操作 安装 我是Ubuntu的环境 执行以下命令来安装 sudo
  • 使用hydra进行FTP认证破解

    hydra入门 hydra是什么 hydra的安装 hydra的基本使用 熟悉常见协议 HTTP协议 FTP协议 SSH协议 Telnet协议 熟悉hydra的参数 基本参数 高级参数 使用方法 使用hydra进行HTTP认证破解 HTTP
  • 搭建机器人电控系统——通信协议——串口通信USART/UART、RS232、RS485及其实例

    通信协议 串口通信详解 IIC通信详解 SPI通信详解 CAN通信详解 文章目录 通信协议 什么是串口 串口分类 USART UART RS232 RS485的区别 串口协议原理 传输协议 需要定义的参数 发送函数USART SendDat
  • Java是一门什么语言?

    个人理解 Java代码需要先编译成class 然后交给JVM执行 而JVM在执行class代码时是解释执行的 所以Java不是一门单纯的编译型或解释型语言 它是一门混合型语言 它是集编译型语言和解释型语言的优势于一身 即执行速度较快 只需编
  • 微调(fine-tuning)

    微调 fine tuing 是一种迁移学习 transfer learning 方法 在迁移学习过程中 预训练的模型的权重会根据新数据进行训练和调整
  • Python工程师面试必备25条知识点

    1 到底什么是Python 你可以在回答中与其他技术进行对比 Python是一种解释型语言 与C语言和C的衍生语言不同 Python代码在运行之前不需要编译 其他解释型语言还包括PHP和Ruby Python是动态类型语言 指的是你在声明变
  • Vue实现高德地图信息窗

  • 操作系统——读者写者问题(写者优先)

    阅读前提醒 本文代码为伪代码 仅供理解 马上就要被关得精神失常了 也许这是我的最后一条博客了吧 啊哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈水文来咯 1 什么是读者写者问题 一个数据文件或记录可被多个进程共享
  • 当pytest遇上poium会擦出什么火花 ?

    首先 创建一个test sample test demo py 文件 写入下面三行代码 def test bing page page get https www bing com assert page get title 必应 不要问题
  • 栈和队列-P79-9

    队列的最大容量为MaxSize 这句话并不是说该队列存满时的元素个数为MaxSize 这一种情况是最大容量为MaxSize 没有申请其他数据成员 判断队列满的条件是Q front Q rear 1 MaxSize 解释 通俗的解释 Q re
  • 强化学习:带起始探索的每次访问同策回合更新算法求解机器人找金币问题

    1 问题描述 2 环境建模 3 游戏环境类roadenv 设计 class roadenv def init self epsilon 0 5 gamma 0 8 状态空间 动作空间 self states 1 2 3 4 5 6 7 8