强化学习实践(二):Dynamic Programming(Value \ Policy Iteration)

news2024/11/27 14:35:34

强化学习实践(二):Dynamic Programming(Value \ Policy Iteration)

  • 伪代码
    • Value Iteration
    • Policy Iteration
    • Truncated Policy Iteration
  • 代码
  • 项目地址

伪代码

具体的理解可以看理论学习篇,以及代码中的注释,以及赵老师原著

Value Iteration

在这里插入图片描述

Policy Iteration

在这里插入图片描述

Truncated Policy Iteration

在这里插入图片描述

代码

import numpy as np

from environment.env import Env
from environment.vis import Vis


class DynamicProgramming:
    """
    动态规划的两个方法, 实际都为Truncated Policy Iteration, 具体代码尽量复刻伪代码的逻辑
    """

    def __init__(self, gamma: float = 0.9, env: Env = None, vis: Vis = None, render: bool = False):
        self.gamma = gamma
        self.env = env
        self.vis = vis
        self.render = render
        self.policy = np.zeros(shape=(self.env.state_space_size, self.env.action_space_size), dtype=int)
        self.qtable = np.zeros(shape=self.env.state_space_size, dtype=float)

    def value_iteration(self, threshold: float = 0.01) -> None:
        """
        计算每个状态动作对的状态动作价值,然后每个状态选择最大的值对应的动作作为自己的策略,并将值作为自己的状态价值
        根据Contraction Mapping Theorem, qsa的计算公式满足该理论要求,通过迭代不断优化全局状态价值,并找到对应的最优策略
        :param threshold: 迭代结束的阈值,前后两次迭代后的全局状态价值的欧氏距离相差小于该阈值时代表优化空间已经不大,结束优化
        :return: None
        """
        differ = np.inf
        while differ > threshold:
            kth_qtable = self.qtable.copy()
            for state in self.env.state_space:
                qsa = np.zeros(shape=self.env.action_space_size, dtype=float)
                for action in self.env.action_space:
                    qsa[action] = self.calculate_qvalue(state, action)
                self.policy[state] = np.zeros(shape=self.env.action_space_size)
                self.policy[state, np.argmax(qsa)] = 1
                self.qtable[state] = np.max(qsa)
            differ = np.linalg.norm(kth_qtable - self.qtable, ord=1)
        if self.render:
            self.vis.show_policy(self.policy)
            self.vis.show_value(self.qtable)
            self.vis.show()

    def policy_iteration(self, policy_threshold: float = 0.01, value_threshold: float = 0.01, steps: int = 10) -> None:
        """
        step 1:从初始策略开始,求解该策略对应的全局状态价值(在这个过程中本来要无穷次迭代得到真正的状态价值,但实际会设置阈值,截断策略迭代算法)
        step 2:拿到第K次迭代对应的策略求解出的全局状态价值之后,利用该价值作为初始值,再进行全局状态价值优化以及策略优化
        这个过程其实相较于值迭代比较难理解

        Q1:In the policy evaluation step, how to get the state value vπk by solving the Bellman equation?
        A1:x=f(x)这种满足Contraction Mapping Theorem的迭代求解方式(也可以解析解matrix vector form,但是涉及矩阵逆运算会很慢O(n^3))
        Q2*:In the policy improvement step, why is the new policy πk+1 better than πk?
        A2:直观上不是很好理解就得利用数学工具了,赵老师原著Chapter4.P73页对比了前后两次迭代证明了Vπk - Vπk+1 < 0
        Q3*:Why can this algorithm finally converge to an optimal policy?
        A3:Chapter4.P75页不仅证明了能达到最优,而且引入这种PE过程会收敛得更快,证明了Vπk>Vk,同一个迭代timing,策略迭代状态价值更接近最优

        :param policy_threshold: 策略阈值
        :param value_threshold: 全局状态价值阈值
        :param steps: 截断的最大迭代次数,只用阈值也行,但这样更方便说明
        :return: None
        """
        policy_differ = np.inf
        self.init_policy()
        while policy_differ > policy_threshold:
            kth_policy = self.policy.copy()
            # step 1: policy evaluation
            value_differ = np.inf
            while value_differ > value_threshold and steps > 0:
                steps -= 1
                kth_qtable = self.qtable.copy()
                for state in self.env.state_space:
                    state_value = 0
                    for action in self.env.action_space:
                        state_value += self.policy[state, action] * self.calculate_qvalue(state, action)
                    self.qtable[state] = state_value
                value_differ = np.linalg.norm(kth_qtable - self.qtable, ord=1)
            # step 2: policy improvement 相当于上面的PE给下面提供了一个初始状态(对应策略),之前值迭代的时候是全0为初始值
            value_differ = np.inf
            while value_differ > value_threshold:
                kth_qtable = self.qtable.copy()
                for state in self.env.state_space:
                    qsa = np.zeros(shape=self.env.action_space_size, dtype=float)
                    for action in self.env.action_space:
                        qsa[action] = self.calculate_qvalue(state, action)
                    self.policy[state] = np.zeros(shape=self.env.action_space_size)
                    self.policy[state, np.argmax(qsa)] = 1
                    self.qtable[state] = np.max(qsa)
                value_differ = np.linalg.norm(kth_qtable - self.qtable, ord=1)
            policy_differ = np.linalg.norm(kth_policy - self.policy, ord=1)
        if self.render:
            self.vis.show_policy(self.policy)
            self.vis.show_value(self.qtable)
            self.vis.show()

    def init_policy(self) -> None:
        """
        之前值迭代可以不用初始化,因为只对policy进行了更新,现在策略迭代得初始化,因为首先就要利用policy进行PE
        :return: None
        """
        random_action = np.random.randint(self.env.action_space_size, size=self.env.state_space_size)
        for state, action in enumerate(random_action):
            self.policy[state, action] = 1

    def calculate_qvalue(self, state: int, action: int) -> float:
        """
        计算状态动作价值函数的元素展开式, 这里就能理解为什么环境模型为什么是这样的数据结构
        :param state: 当前状态
        :param action: 当前动作
        :return: 当前的状态动作价值
        """
        qvalue = 0
        # immediately reward: sigma(r * p(r | s, a))
        for reward_type in range(self.env.reward_space_size):
            qvalue += self.env.reward_space[reward_type] * self.env.rewards_model[state, action, reward_type]
        # next state expected reward : sigma(vk(s') * p(s' | s, a))
        for next_state in range(self.env.state_space_size):
            qvalue += self.gamma * self.env.states_model[state, action, next_state] * self.qtable[next_state]
        return qvalue


if __name__ == "__main__":
    start_state = [0, 0]
    target_state = [2, 3]
    forbid = [[2, 2], [2, 1], [1, 1], [3, 3], [1, 3], [1, 4]]
    model = DynamicProgramming(vis=Vis(target_state=target_state, forbid=forbid),
                               env=Env(target_state=target_state, forbid=forbid),
                               render=True)
    model.value_iteration()
    # model.policy_iteration()

项目地址

RL_Algorithms(正在逐步更新多智能体的算法,STAR HOPE(^ - ^)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2100039.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Shader学习笔记

1. 渲染管线概述 定义&#xff1a;渲染管线&#xff08;流水线&#xff09;就是将数据分阶段的变为屏幕图像的过程 数据就是我们在游戏场景中放置的模型、光源、摄像机等等内容的数据 阶段就是渲染管线中的三个阶段&#xff1a;应用阶段一>几何阶段一>光栅化阶段 通过这…

超详细步骤——Keil MDK-ARM 如何修改工程名字

背景&#xff1a; 注意&#xff1a;本项目是基于 STM32 单片机的裸机程序&#xff0c;使用 STM32CubeMX 工具生成的 Keil MDK-ARM 工程。 目标&#xff1a; 在 Keil MDK-ARM 开发环境中&#xff0c;将名为version0805 的工程重命名为 version0910&#xff0c;并确保所有新编译…

PHP+Thinkphp+MySQL民宿管理系统41279-计算机毕业设计项目选题推荐(免费领源码)

摘 要 伴随着国内旅游经济的迅猛发展民宿住宿行在国内也迎来了前所未有的发展机遇。传统的旅游模式已难以满足游客日益多元化的需求&#xff0c;随着人们外出度假的时间越来越长&#xff0c;导致人们在住宿的选择上更加追求舒适、个性化的住宿体验。以往大家出游度假首选都是以…

Android图片缓存工具类LruCache原理和使用介绍

LruCache & DiskLruCache原理。 常用的三级缓存主要有LruCache、DiskLruCache、网络&#xff0c;其中LruCache对应内存缓存、 DiskLruCache对应持久化缓存。Lru表示最近最少使用&#xff0c;意思是当缓存到达限制时候&#xff0c;优先淘汰近 期内最少使用的缓存&#xff0c…

传输层协议---TCP协议

以下都是自己的学习总结&#xff0c;有不足也有错误的地方&#xff0c;谨供参考。 TCP协议特点 ---面向字节流&#xff0c;有连接&#xff0c;可靠&#xff0c;全双工 面向字节流 面向字节流指的是服务器和客户端之间的数据传输&#xff0c;使用的字节流传输&#xff0c;获取…

Git 使用指南 --- 远程仓库

序言 在这篇文章中&#xff0c;我们将理解分布式版本控制系统&#xff0c;学习远程仓库与本地仓库的交互操作&#xff0c;掌握多⼈协作开发模式。 1. 理解分布式版本控制系统 前两篇中的所有内容都是针对于在本地的文件管理&#xff0c;Git 的强大之处肯定不仅仅只是体现于此。…

jupter_notebook简单介绍以及安装使用

目录 jupyter简单介绍&#xff1a; Jupyter&#xff1a; Jupyter的主要特点包括&#xff1a; 1. 交互式编程&#xff1a; 2. 文档和代码的整合&#xff1a; 3. 易于分享和协作&#xff1a; 4. 丰富的扩展性&#xff1a; 5. 社区支持&#xff1a; 6. 支持多种内核&#…

基于SpringBoot房屋租赁管理系统【包含运行步骤】

基于SpringBoot房屋租赁管理系统【包含运行步骤】 一、项目简介二、技术选型三、运行步骤1. 项目启动 四、项目演示前台页面展示管理员后台管理源码获取方式 总结 大家好&#xff0c;这里是程序猿代码之路&#xff0c;在当今社会&#xff0c;随着城市化进程的加快&#xff0c;房…

Git之2.29版本重要特性及用法实例(六十二)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者. 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列…

亿图机床采集数据

这个数控系统的英文名是HUST,在台湾知名度还可以,但大陆这边我做这么多年项目也只接触过屈指可数的几次,可见市场占有率并不大。下面是一些介绍: 台灣億圖 HUST CNC 是一個充滿活力的公司,我們經營的目標是提供能滿足客戶之優良產品,以及優質的服務。我們的期望是使 HUS…

学习笔记--Docker

安装 1.卸载旧版 首先如果系统中已经存在旧的Docker&#xff0c;则先卸载&#xff1a; yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 2.配置Docker的yum库 首先要安…

七,Spring Boot 当中的 yaml 语法使用

七&#xff0c;Spring Boot 当中的 yaml 语法使用 文章目录 七&#xff0c;Spring Boot 当中的 yaml 语法使用1. yaml 的介绍2. yaml 基本语法3. yaml 数据类型4. 学习测试的准备工作4.1 yaml 字面量4.2 yaml 数组4.3 yaml 对象 5. yaml 使用细节和注意事项6. 总结&#xff1a;…

产业园区智慧招商解决方案

1. 项目背景与挑战 2023年&#xff0c;产业园区在智慧招商领域面临诸多挑战&#xff0c;包括传统推广方式、信息分散、跨部门协作障碍、缺乏主动服务、服务流程改进困难以及数据档案管理不善。 2. 方案思路 解决方案围绕“一套秘籍”和“一套流程”&#xff0c;服务三方角色…

OpenAI即将推出自然语音功能

&#x1f989; AI新闻 &#x1f680; OpenAI即将推出自然语音功能 摘要&#xff1a;测试博客testingcatalog揭示OpenAI正在通过逆向工程ChatGPT应用&#xff0c;计划增加更自然的语音朗读功能。未来可能推出8种新语音&#xff0c;具有独特代号&#xff0c;能表达动物叫声等非…

(苍穹外卖)day05 店铺营业状态设置 功能测试

目录 一.Redis入门 Redis简介 二.Redis数据类型 三.Redis常用命令 字符串操作命令 哈希操作命令 列表操作命令 集合操作命令 有序集合操作命令 通用命令 四.在java中操作Redis Redis的java客户端 ​编辑 五.店铺营业状态设置 代码开发 Redis---是一个数据库&…

浅谈信创浪潮下,职业院校人才培养有哪些新思路

一、信创产业发展背景 1.1 国家战略意义 信创产业&#xff0c;即信息技术应用创新产业&#xff0c;是国家战略发展的关键方向。近年来&#xff0c;在全球化的竞争和合作背景下&#xff0c;中国高度重视信息技术的自主创新能力&#xff0c;通过政策扶持、资金投入和市场引导等…

【数据结构】—— 栈与队列

目录 前言一、栈1.1 堆栈原理1.2 栈的实现 二、队列2.1 队列的概念2.2 队列结构2.2.1 顺序队列2.2.2 链队 2.3 队列的实现 三、堆与栈的区别3.1 内存中的堆与栈3.2 数据结构中的堆与栈 结语 前言 在单片机数据处理的时候&#xff0c;如果在中断里添加太多函数&#xff0c;可能会…

使用mobaxterm连接linux出现连接中断问题

1.问题描述 使用mobaxterm在连接到远程服务器时&#xff0c;如果隔一段时间不进行操作的话&#xff0c;会出现中断连接的现象。 2.解决 为了增强Linux系统的安全性&#xff0c;我们需要在用户输入空闲一段时间后自动断开&#xff0c;这个操作可以由设置TMOUT值来实现。将以下…

netty编程之基于websocket实现聊天功能

写在前面 源码 。 本文看下netty如何通过websocket实现聊天功能。 类似于实现http server,netty实现websocket也很简单&#xff0c;同样使用对应的编码器和解码器就行了&#xff0c;相关的有HttpServerCodec,HttpObjectAggregator,ChunkedWriteHandler。 1&#xff1a;编码 …

已解决:VS2022启动闪退,错误模块名称: clr.dll,版本: 4.8.9261.0,时间戳: 0x667a1925的问题

本问题已得到解决&#xff0c;请看以下小结&#xff1a; 关于《VS2022启动闪退》的解决方案 记录备注报错时间2024年报错版本VS2022报错复现下载某款VPN软件后&#xff0c;打开VS2022闪退&#xff0c;事件查看器输出如下报错描述错误应用程序名称: devenv.exe&#xff0c;版本:…