news 2026/4/18 10:39:38

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

作者头像

张小明

前端开发工程师

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

基本思想:

MC_basic.py

注意:由于使用贪心策略,因此不支持stochastic策略。

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): 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.policy = np.zeros((self.state_space_size, self.action_space_size)) self.policy[:,0]=1.0 # 初始动作都是向上 self.action_value = np.zeros((self.state_space_size, self.action_space_size, self.samples)) # action value q(s,a) self.state_value= np.zeros((self.env.size,self.env.size)) def solve(self, iterations=20): for i in range(iterations): for s in range(self.state_space_size): for a in range(self.action_space_size): for k in range(self.samples): # 从(s,a)出发,遵循策略policy采样若干个episodes,并获得return的平均值 episodes = self.generate_episodes(s, a) returns = self.compute_returns(episodes) self.action_value[s,a,k]=returns qvalues = self.action_value.mean(axis=2) # k次采样的平均值 shape: [state_size, 5] best_a = np.argmax(qvalues, axis=1) # 每个state使得平均return最大的action index shape: [state_size] for s in range(self.state_space_size): if s in self.env.terminal: self.policy[s] = np.eye(self.action_space_size)[4] continue else: a_star = best_a[s] # 当前状态 s 的最优动作 index self.policy[s] = np.eye(self.action_space_size)[a_star] self.state_value = np.sum(self.policy * 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 compute_returns(self, episodes): ''' :param episodes: 一条轨迹 [(state_id, action,reward),(...)] :return: 一条轨迹的累计return ''' G = 0 for (_, _, r) in reversed(episodes): G = r + self.gamma * G # 最后一步->第一步 return G if __name__ == '__main__': # transition_prob = { # "forward": 0.8, # "left": 0.05, # "right": 0.15 # } env = GridWorldEnv( size=5, forbidden=[(1, 2),(2,4)], terminal=[(4, 4)], r_boundary=-10, r_other=0, r_terminal=1, r_forbidden=-1 ) vi = MonteCarloPolicyIteration(env=env, gamma=0.9) vi.solve(iterations=20) print("\n state value: ") print(vi.state_value) print("\n 策略 π(s):") print(vi.policy) drow_policy(vi.policy, env)

env.py修改地方:

1. self.terminal和self.forbidden存储termina和forbiddenl对应的state_id,而不是传入的list。修改后要修改其他是用到self.terminal和self.forbidden的地方。

self.terminal = {self.state_id(x, y) for (x, y) in terminal} self.forbidden = {self.state_id(x, y) for (x, y) in forbidden} def build_reward_list(self): reward = set() reward.add(self.r_forbidden) reward.add(self.r_other) reward.add(self.r_terminal) reward.add(self.r_boundary) self.reward_list = sorted(list(reward)) self.reward_space_size = len(self.reward_list)

2. 分别为边界、其他、forbidden、terminal设置reward,而不是使用传入的list列表。

def __init__(self, size: int, terminal, forbidden, r_forbidden=-1, r_other=0, r_terminal=1, r_boundary=-1, transition_prob=None): ... self.r_forbidden = r_forbidden self.r_other = r_other self.r_terminal = r_terminal self.r_boundary = r_boundary ...

3. 新增step方法。

def step(self, state, action): ''' :param action: 当前所在的state_id :param action: 当前采取的动作 :return: state,reward,done 到达的下一个状态的state_id,获取的奖励,是否走到了终点 ''' if state in self.terminal: return state, self.r_terminal, True i, j = divmod(state, self.size) moves = { 0: (-1, 0), # 上 1: (0, 1), # 右 2: (1, 0), # 下 3: (0, -1), # 左 4: (0, 0) # 原地 } di, dj = moves[action] ni, nj = i + di, j + dj 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) reward = self.reward_func(state, next_state, action) done = next_state in self.terminal return next_state, reward, done

相同配置下,policy iteration, value iteration与MC PI运行结果:

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

数据结构:有向无环图

有向无环图 资料&#xff1a;https://pan.quark.cn/s/43d906ddfa1b、https://pan.quark.cn/s/90ad8fba8347、https://pan.quark.cn/s/d9d72152d3cf 一、有向无环图的定义 有向无环图&#xff08;Directed Acyclic Graph&#xff0c;简称DAG&#xff09;是一类特殊的有向图&…

作者头像 李华
网站建设 2026/4/11 19:17:21

13、Linux 文件归档、压缩与查找实用指南(上)

Linux 文件归档、压缩与查找实用指南(上) 在当今数字化时代,我们面临着海量文件的管理挑战,无论是归档压缩以节省空间,还是快速准确地查找所需文件。Linux 提供了一系列强大的工具来应对这些问题,下面将为你详细介绍相关的操作和技巧。 1. 使用 tar 和 gzip 进行文件归…

作者头像 李华
网站建设 2026/4/17 18:44:59

微信小程序任务管理终极指南:5分钟打造高效待办系统

微信小程序任务管理终极指南&#xff1a;5分钟打造高效待办系统 【免费下载链接】weapp-todos 一个简单的任务清单小程序, awesome weapp demo, todos, todolist 项目地址: https://gitcode.com/gh_mirrors/we/weapp-todos 在快节奏的现代生活中&#xff0c;高效的任务管…

作者头像 李华
网站建设 2026/4/18 8:30:36

Captura视频录制与防抖功能配置完全指南

Captura视频录制与防抖功能配置完全指南 【免费下载链接】Captura Capture Screen, Audio, Cursor, Mouse Clicks and Keystrokes 项目地址: https://gitcode.com/gh_mirrors/ca/Captura 屏幕录制是现代工作学习中不可或缺的工具&#xff0c;但你是否遇到过录制视频时画…

作者头像 李华
网站建设 2026/4/18 8:15:08

Llama-Factory是否支持模型剪枝?轻量化部署方案

Llama-Factory是否支持模型剪枝&#xff1f;轻量化部署方案 在大语言模型&#xff08;LLM&#xff09;快速演进的今天&#xff0c;越来越多的企业和开发者希望将强大的生成能力落地到实际业务中。然而&#xff0c;动辄数十GB显存需求、上百亿参数规模的模型让许多团队望而却步—…

作者头像 李华
网站建设 2026/4/18 7:58:16

56、Linux网络服务配置与安全指南

Linux网络服务配置与安全指南 1. 探索练习 在网络配置和管理中,我们常常会遇到各种实际问题,以下是一些探索性的练习,帮助我们更好地理解和应用网络知识。 1. 子网划分问题 :假设公司使用A类网络100.0.0.0/8,若要将此网络划分为11个子网以匹配11个部门,需要为网络上…

作者头像 李华