Week 3 - 学生练习

练习目标

  • 巩固对最优价值函数 (\(V^*\), \(Q^*\)) 和最优策略 (\(\pi^*\)) 概念的理解。
  • 理解 Bellman 最优方程与 Bellman 期望方程的关键区别(max 操作)。
  • 练习使用 Gym/Gymnasium 环境进行基本交互 (reset, step, render)。
  • 将商业场景概念化为 Gym 环境要素,为后续 Lab 做准备。

练习内容

练习 1: 最优价值函数与策略

假设在一个简单的 Gridworld 中,我们已经通过某种方法得到了最优动作值函数 \(Q^*(s, a)\),如下表所示(\(s\) 代表格子坐标,\(a\) 代表动作:0上, 1右, 2下, 3左):

状态 \(s\) (r,c) \(Q^*(s, 0)\) \(Q^*(s, 1)\) \(Q^*(s, 2)\) \(Q^*(s, 3)\)
(0,0) -1.5 0.5 -0.8 -1.2
(0,1) -0.2 1.0 0.3 -0.5
(1,0) 0.8 -0.1 -1.0 -0.6
(1,1) 0.2 0.5 0.9 0.1
  1. 请根据上表,确定在每个状态下的最优策略 \(\pi^*(s)\) (即应该选择哪个动作?)。
  2. 请计算每个状态的最优状态值函数 \(V^*(s)\)

练习 2: Bellman 方程辨析

请判断以下描述是关于 Bellman 期望方程还是 Bellman 最优方程,并简述理由:

  1. 这个方程描述了在遵循某个特定策略 \(\pi\) 时,一个状态的价值与其后继状态价值之间的关系。
  2. 这个方程中包含了 max 操作,体现了在每个状态选择最优动作的思想。
  3. 求解这个方程(如果模型已知)可以得到某个给定策略 \(\pi\) 的价值函数 \(V_\pi\)\(Q_\pi\)
  4. 求解这个方程(如果模型已知)可以直接得到最优价值函数 \(V^*\)\(Q^*\),进而得到最优策略 \(\pi^*\)
  5. Q-Learning 算法的更新规则是基于这个方程的采样近似。
  6. SARSA 算法的更新规则是基于这个方程的采样近似。

练习 3: Gym 环境交互练习

本练习旨在让你熟悉 Gym/Gymnasium 的基本交互循环。请完成以下步骤:

  1. 选择环境: 选择一个你感兴趣的、离散动作空间的经典控制环境,例如:
    • "CartPole-v1" (小车杆)
    • "Acrobot-v1" (双连杆)
    • "MountainCar-v0" (小车爬山)
    • "Blackjack-v1" (二十一点)
    • 或者上周 Lab 1 中你尝试过的其他环境。
  2. 编写代码: 编写一个 Python 脚本,完成以下操作:
    • 导入 gymnasium 库。
    • 使用 gym.make() 创建你选择的环境实例,并设置 render_mode="human" 以便可视化。
    • 重置 (reset) 环境,获取初始状态 observation
    • 循环执行 100 步:
      • 在每一步,随机选择一个合法的动作 (env.action_space.sample())。
      • 执行 (step) 这个动作,获取 observation, reward, terminated, truncated, info
      • 打印 当前步数、选择的动作、获得的奖励、是否终止 (terminated)、是否截断 (truncated)。
      • 渲染 (render) 环境。
      • 检查 如果 terminatedtruncatedTrue,则重置环境,并跳出当前循环(或者你可以选择继续执行完 100 步,但在结束后重置)。
    • 循环结束后,关闭 (close) 环境。
  3. 运行代码并观察: 运行你的脚本,观察环境的可视化窗口以及打印输出的信息。确保你理解每一步发生了什么。
  4. 粘贴代码: 将你编写的 Python 脚本代码粘贴到你的答案中。

练习 4: 商业场景 Gym 环境要素定义 (深化)

回顾你在 Week 1 或 Week 2 练习中定义的一个商业场景(如库存管理、资源分配、广告投放等)。现在,请更具体地思考如何将其映射到 Gym 环境的要素,特别是状态和动作空间:

  1. 状态空间 (Observation Space):
    • 如果状态包含连续变量(如库存量、剩余时间),你会如何处理?是直接使用连续值(需要函数逼近),还是进行离散化/分箱?如果离散化,你打算如何划分区间?
    • 如果状态包含多个变量,你会如何将它们组合成一个状态表示?(例如,一个 NumPy 数组或字典?)
    • 使用 gymnasium.spaces 中的哪种空间类型(如 spaces.Discrete, spaces.Box, spaces.Dict)来定义你的状态空间比较合适?请写出你选择的空间定义代码(例如 spaces.Discrete(10)spaces.Box(low=0, high=100, shape=(1,), dtype=np.int32))。
  2. 动作空间 (Action Space):
    • 你的动作是离散的还是连续的?
    • 使用 gymnasium.spaces 中的哪种空间类型来定义你的动作空间比较合适?请写出你选择的空间定义代码。
  3. (思考) 相比于简单的概念定义,将问题具体化为 Gym 的空间定义,会遇到哪些新的挑战或需要做的决策?

提交要求

  • 请将你的答案整理成一个文档(如 Word, PDF, 或 Markdown 文件)。
  • 对于练习 1 和 2,请给出明确的答案和理由。
  • 对于练习 3,请粘贴你编写的 Python 代码。
  • 对于练习 4,请详细描述你对状态空间和动作空间的思考与定义,并写出对应的 gymnasium.spaces 定义代码。
  • 文件命名格式:姓名_学号_Week3_Exercise.xxx
  • 通过教学平台提交。