news 2026/8/22 0:13:19

强化学习蒙特卡洛策略迭代方法求最优策略的代码实现(二)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
强化学习蒙特卡洛策略迭代方法求最优策略的代码实现(二)

这里直接融合了first visit和every visit,当选择every visit,策略更新使用stochastic的epsilon greedy;选择first visit,策略更新使用greedy。

理论基础:

需要说明:

1. 由于我发现agent大多数时候更倾向于呆在原地,因为走到终点的reward太小,而走到forbidden或者boundary的reward又是很大的负数,因此呆在原地是长远考虑。因此我增加了r_stay,当模型决定留在原地就给一定的惩罚。在env.py中添加即可。同时注意测试时r_boundary和r_forbidden不应该设置的太小。

2. 在env.py的step方法中需要调整,可以允许agent进入forbidden区域。

if not (0 <= ni < self.size and 0 <= nj < self.size): next_state = self.state_id(i,j) else: next_state = self.state_id(ni,nj)
from collections import defaultdict import numpy as np from env import GridWorldEnv from utils import drow_policy class MonteCarloPolicyIteration(object): def __init__(self, env: GridWorldEnv, gamma=0.9, samples=1, mode="first visit"): self.env = env self.action_space_size = self.env.num_actions # 上下左右原地 self.reward_space_size = self.env.reward_space_size # 执行每个动作的reward self.state_space_size = self.env.num_states self.reward_list = self.env.reward_list self.gamma = gamma self.samples = samples self.mode = mode self.policy = np.ones((self.state_space_size, self.action_space_size)) / self.action_space_size self.state_value = np.zeros((self.env.size, self.env.size)) self.qvalues = np.zeros((self.state_space_size, self.action_space_size)) self.returns = np.zeros((self.state_space_size, self.action_space_size)) # 必须初始化为0,不是zeros_like self.nums = np.zeros((self.state_space_size, self.action_space_size)) def solve(self, iterations=20, epsilon=0.1): ''' :param iterations: 迭代的次数 :param epsilon: epsilon greedy:[0,1] epsilon=0:greedy,就选择best action;epsilon=1:stochastic,选择所有action的概率相同 ''' for i in range(iterations): for _ in range(self.samples): # 随机选择一个非终点状态作为起始状态,确保所有的状态都能被充分访问 non_terminal_states = [i for i in range(self.state_space_size) if i not in self.env.terminal] s = np.random.choice(non_terminal_states) a = np.random.choice(self.action_space_size, p=self.policy[s]) # 按policy采样 episode = self.generate_episodes(s, a) self.update_q_from_episode(episode) for s in range(self.state_space_size): if s in self.env.terminal: self.policy[s] = np.eye(self.action_space_size)[4] else: best_a = np.argmax(self.qvalues[s]) if self.mode=="every visit": # 如果是first visit,很多(s,t)可能被访问了很多次,但是却只用它做了一次action value的估计 # epsilon greedy self.policy[s] = epsilon / self.action_space_size # 给其他action小概率 self.policy[s, best_a] += 1 - epsilon # 给最有可能的action大概率 elif self.mode=="first visit": # 实际对应epsilon=0的情况 self.policy[s]=np.eye(self.action_space_size)[best_a] self.state_value = np.sum(self.policy * self.qvalues, axis=1).reshape(self.env.size, self.env.size) def generate_episodes(self, start_state, start_action, max_steps=200): ''' :param start_state: 当前状态的state_id :param start_action: 当前动作 :return: [(state_id, action,reward),(...)] ''' episode = [] state = start_state action = start_action for _ in range(max_steps): next_state, reward, done = self.env.step(state, action) episode.append((state, action, reward)) if done: break state = next_state action = np.random.choice(self.action_space_size, p=self.policy[state]) # 从[0,action_space_size)随机选一个,每个action的概率为policy[state] return episode def update_q_from_episode(self, episode): G = 0 visit = set() for s, a, r in reversed(episode): # 如果直接使用reversed(episode)就会同时把tuple内部也反转了 G = r + self.gamma * G if self.mode == "first visit": if (s, a) not in visit: self.returns[s, a] += G self.nums[s, a] += 1 self.qvalues[s, a] = self.returns[s, a] / self.nums[s, a] elif self.mode == "every visit": self.returns[s, a] += G self.nums[s, a] += 1 self.qvalues[s, a] = self.returns[s, a] / self.nums[s, a] else: raise Exception("Invalid mode") if __name__ == '__main__': env = GridWorldEnv( size=5, forbidden=[(1, 2),(3,3)], terminal=[(4,4)], r_boundary=-1, r_other=-0.04, r_terminal=1, r_forbidden=-1, r_stay=-0.1 ) vi = MonteCarloPolicyIteration(env=env, gamma=0.9, samples=10, mode="every visit") vi.solve(iterations=10000, epsilon=0.3) # 只有mode="every visit"才需要传入epsilon print("\n state value: ") print(vi.state_value) drow_policy(vi.policy, env)

对于相同的配置,iteration=100、1000、10000时,策略分别是

可以发现,iteration越大,策略越优。

由于stochastic,因此相同的配置运行多次结果也很大概率不同,大多数时候agent在进行一些exploration,因此看起来策略并不是最好的。因此epsilon greedy实际上是牺牲了最优性,换取了更多的exploration,epsilon越小,越接近最优greedy,epsilon越大,跑的时间也越长。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/21 13:21:29

30秒创建测试:用tar命令快速构建虚拟文件环境

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个测试环境快速生成工具&#xff0c;用户可以选择预设模板&#xff08;如Web项目目录、日志文件结构、数据库备份等&#xff09;或自定义目录结构&#xff0c;系统自动生成对…

作者头像 李华
网站建设 2026/8/20 23:46:59

5分钟掌握IDM试用期重置:告别30天限制的解决方案

还在为IDM试用期到期而烦恼吗&#xff1f;每次试用期结束就要重新安装系统或者寻找替代方案&#xff1f;现在&#xff0c;通过一款专业的IDM试用期重置工具&#xff0c;你可以轻松实现试用期延长&#xff0c;无需修改核心文件&#xff0c;安全可靠。这款基于AutoIt开发的开源工…

作者头像 李华
网站建设 2026/8/21 0:14:46

智汇全球设施农业 2026年北京两大盛会并行 引领产业高质量发展

为全面贯彻国家关于建设农业强国、加快现代设施农业发展战略部署&#xff0c;落实《全国现代设施农业建设规划&#xff08;2023—2030年&#xff09;》目标任务&#xff0c;推动设施农业集约化、智能化、绿色化转型。助力农业现代化进程&#xff0c;2026年3月30日至4月1日&…

作者头像 李华
网站建设 2026/8/21 20:24:55

网络安全零基础入门:一份超详细的知识体系与系统学习路线

第一章&#xff1a;网络安全的基本概念和术语 网络安全是指保护网络系统、硬件、软件、数据以及用户的隐私和权益&#xff0c;防止其受到未经授权的访问、篡改、窃取或破坏。以下是一些网络安全的基本概念和术语&#xff1a; 漏洞&#xff08;Vulnerability&#xff09;&…

作者头像 李华
网站建设 2026/8/21 12:50:18

戴森电池管理技术深度解析:开源固件如何突破原厂限制

戴森电池管理技术深度解析&#xff1a;开源固件如何突破原厂限制 【免费下载链接】FU-Dyson-BMS (Unofficial) Firmware Upgrade for Dyson V6/V7 Vacuum Battery Management System 项目地址: https://gitcode.com/gh_mirrors/fu/FU-Dyson-BMS 在戴森V6和V7吸尘器的电池…

作者头像 李华
网站建设 2026/8/21 22:16:59

我的转行辛酸史:28岁从大专跨界网络安全,这8条教训让我脱胎换骨

网络安全行业 “人才缺口 300 万 、平均年薪超 25 万” 的红利&#xff0c;让无数职场人动了转行心思。尤其是学历普通&#xff08;如大专&#xff09;的群体&#xff0c;既面临原有岗位的天花板&#xff0c;又渴望通过技术转型实现薪资跃迁。但网安行业看似门槛低&#xff0c;…

作者头像 李华