蒙特卡洛方法(MC Exploring Starts算法例子)

 本文章中使用的算法和例子来源于bilibili中西湖大学赵世钰老师的【强化学习的数学原理】课程。网址:第5课-蒙特卡洛方法(MC Exploring Starts算法)_哔哩哔哩_bilibili

目录

一、算法简介

二、相关定义

1、策略评估

2、visit定义

3、episode定义

三、算法流程

四、代码演示


一、算法简介

        "Monte Carlo Exploring Starts"(MC Exploring Starts)是一种强化学习算法,用于估计策略下的状态-动作值函数 Q(s,a)。该方法适用于有限状态和动作空间的问题,主要用于确定性策略的优化。它属于蒙特卡洛(Monte Carlo)方法的一类,使用从起始状态到终止状态的完整回合(episode)进行学习。

二、相关定义

1、策略评估

①每次访问(Every-Visit)蒙特卡洛策略评估:每次一个 (状态动作)对出现在一个 episode 中时,都会对其进行一次回报更新。

②首次访问(First-Visit)蒙特卡洛策略评估:在一个 episode 中,只对某个 (状态,动作) 对的首次访问进行回报更新。即在一个 episode 中,如果某个 (状态,动作) 对已经更新过,就不再更新。

Every-Visit 和 First-Visit 的对比

策略评估方法是否更新重复访问的状态数据量收敛速度适用场景
每次访问较快适用于频繁访问的状态,数据充分时
首次访问较慢适用于减少计算量和数据冗余的情况

2、visit定义

        对于从棋盘格中的一个位置出发,每一个状态-动作组成的一个元组称为一个visit,如(s1,a2),(s2,a4),(s1,a2)……,如此定义。

3、episode定义

        从一个位置出发,所有的visit组成一个episode,至于步数可以自己自行设置。

三、算法流程

四、代码演示

import numpy as np
import random
from collections import defaultdict

class BehrmanMC_EGreedy:
    # Attributes
    n, m = None, None  # Chessboard dimensions
    xx, yy = [-1, 0, 1, 0, 0], [0, 1, 0, -1, 0]  # 动作(上、右、下、左、停留)
    s = "↑→↓←O"  # 动作符号
    _lambda = 0.9  # 折扣因子

    # 初始化棋盘格和策略
    chessboard = [
        ["***"],
        ["**#"],
        ["#*x"]
    ]
    policy = [
        [1, 3, 2],
        [2, 3, 3],
        [2, 2, 0]
    ]
    states = None
    Punishment = None

    def __init__(self):
        self.n, self.m = len(self.chessboard), len(self.chessboard[0][0])
        self.init_matrix()
        self.returns = defaultdict(list)  # 用于记录每个 (状态, 动作) 对的累积回报
        self.Q = defaultdict(lambda: [0] * 5)  # 用来存储每个 (状态, 动作) 对的 Q 值

    def init_matrix(self):
        """Initialize chessboard matrix, rewards, states, and policy."""
        self.chessboard = [list(row[0]) for row in self.chessboard]
        self.states = [[0] * self.m for _ in range(self.n)]
        self.Punishment = [[0 if cell == "*" else (-10 if cell == "#" else 1)
                            for cell in row] for row in self.chessboard]

    def next_point(self, x, y, i):
        """Calculate the next position coordinates, returns current position if out of bounds."""
        wall = 0
        nx, ny = x + self.xx[i], y + self.yy[i]
        if 0 <= nx < self.n and 0 <= ny < self.m:
            return nx, ny, wall
        else:
            wall = 1
            return x, y, wall

    def action(self, x, y, i):
        """Return reward for the given action."""
        next_pos = self.next_point(x, y, i)
        if next_pos[2] == 1:
            return -1  # 撞墙
        else:
            return self.Punishment[next_pos[0]][next_pos[1]]

    def generate_episode(self,x,y,action):
        """Generate an episode using Exploring Starts."""
        episode = []
        for t in range(10):  # episode中visit的数量
            reward = self.action(x, y, action)
            episode.append(((x, y), action, reward))
            x, y, _ = self.next_point(x, y, action)
        return episode


    def update_policy(self):
        """Update Q values and policy based on episode results."""
        for x in range(self.n):
            for y in range(self.m):
                for z in range(5):
                    episode_data = self.generate_episode(x,y,z)
                    G = 0
                    visited = set()

                    # 使用首次访问
                    for (x, y), action, reward in reversed(episode_data):
                        G = self._lambda * G + reward
                        if (x, y, action) not in visited:  # Every-visit MC update
                            self.returns[(x, y, action)].append(G)
                            self.Q[(x, y)][action] = np.mean(self.returns[(x, y, action)])
                            visited.add((x, y, action))
                    for (x, y) in self.Q.keys():
                        best_action = np.argmax(self.Q[(x, y)])
                        self.policy[x][y] = best_action  # 将策略更新为最佳动作

    def show_policy(self):
        """Display the final policy matrix."""
        policy_display = "\n".join("\t".join(self.s[self.policy[x][y]] for y in range(self.m)) for x in range(self.n))
        print(policy_display)

if __name__ == '__main__':
    behrman_mc = BehrmanMC_EGreedy()
    behrman_mc.update_policy()  # 实施MC Exploring Starts算法
    behrman_mc.show_policy()  # 输出最终策略

### 关于赵世钰在强化学习中使用的蒙特卡洛方法的研究成果讲解 #### 蒙特卡洛方法概述 蒙特卡洛方法是一种用于解决马尔可夫决策过程中价值函数评估问题的技术。该方法通过完整的序列(episode)来估算动作价值 \( q_\pi(s, a) \)[^1]。具体而言,在给定策略下,从初始状态出发直到终止状态形成一个完整的轨迹,并利用此轨迹中的奖励计算回报。 #### 动作价值的估计方式 为了近似或对 \( q_\pi \) 进行采样,可以采用基于蒙特卡洛方法。对于任意一对状态-行为\( (s, a) \),可以通过执行这一对并获得整个episodic的结果来获取其对应的return \( g \),进而作为 \( q_\pi(s, a) \) 的无偏样本[^2]。 #### 应用实例——REINFORCE算法 当上述蒙特卡洛抽样的概念与policy gradient相结合时,则形成了名为REINFORCE的学习算法。这种组合允许直接优化目标性能指标而无需显式的环境模型描述。 #### 状态价值更新机制 针对特定的状态 \( s \),每当访问到它一次就会增加相应的计数器 \( N(s) \),同时累积实际观察到的折扣累计奖赏 \( G_t \) 到变量 \( M(s) \) 中去;最终,状态的价值可通过简单的算术平均得出\[ V(s) = \frac{M(s)}{N(s)} \][^3]。 ```python def monte_carlo_evaluation(policy, episodes): state_values = defaultdict(float) returns_sum = defaultdict(float) returns_count = defaultdict(int) for _ in range(episodes): states_rewards = generate_episode_from_limit_stochastic(policy) visited_states = set() for idx, (state, _) in enumerate(states_rewards): if state not in visited_states: visited_states.add(state) # Calculate the return from this visit onwards. future_returns = sum([r for (_, r) in states_rewards[idx:]]) returns_sum[state] += future_returns returns_count[state] += 1 state_values[state] = returns_sum[state] / returns_count[state] return dict(state_values) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

edgarrrr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值