Files
RL-Study/Notebooks/C3.ipynb
T
2026-02-27 21:17:25 +08:00

167 lines
6.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "markdown",
"id": "745510b1",
"metadata": {},
"source": [
"# 第 3 章:最优状态价值与贝尔曼最优方程\n",
"\n",
"## 1. 什么是最优策略?\n",
"如果一个策略 $\\pi^*$ 在所有状态下的价值,都大于或等于其他任何策略的价值,即对于所有 $s \\in \\mathcal{S}$,都有 $v_{\\pi^*}(s) \\ge v_\\pi(s)$,那么 $\\pi^*$ 就是最优策略。\n",
"最优策略的状态价值,被称为**最优状态价值 (Optimal State Value)** $v^*$。\n",
"\n",
"## 2. 贝尔曼最优方程 (BOE)\n",
"之前我们算的是某个固定策略的价值。现在我们要算的是“最优”价值。\n",
"BOE 的核心思想是:在某个状态下的最优价值,等于**所有可能动作中,动作价值 $q(s,a)$ 的最大值**。\n",
"\n",
"数学表达为:\n",
"$$v(s) = \\max_{a \\in \\mathcal{A}} q(s,a)$$"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "f31bd6cc",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--- 策略改进演示 ---\n",
"动作 a1 的价值: 6.2\n",
"动作 a2 的价值: 8.0\n",
"动作 a3 的价值: 9.0\n",
"动作 a4 的价值: 6.2\n",
"动作 a5 的价值: 7.2\n",
"\n",
"=> 最佳动作是 'a3',其价值为 9.0。\n",
"结论:只要我们在每个状态都选择 Q 值最大的动作,就能得到一个更好的、甚至是最优的策略!\n"
]
}
],
"source": [
"import numpy as np\n",
"\n",
"# 假设我们在状态 s1 算出了 5 个动作的 Q 值 (参考书中 3.1 节的计算)\n",
"# a1: 向上, a2: 向右, a3: 向下, a4: 向左, a5: 原地不动\n",
"q_values_s1 = {\n",
" \"a1\": 6.2, # 撞墙,-1 + 0.9*v(s1)\n",
" \"a2\": 8.0, # 原策略向右,进禁区,-1 + 0.9*v(s2)\n",
" \"a3\": 9.0, # 向下避开禁区,0 + 0.9*v(s3)\n",
" \"a4\": 6.2, # 撞墙,-1 + 0.9*v(s1)\n",
" \"a5\": 7.2 # 原地不动,0 + 0.9*v(s1)\n",
"}\n",
"\n",
"# 寻找使 Q 值最大的动作 (贪心策略 Greedy Policy)\n",
"best_action = max(q_values_s1, key=q_values_s1.get)\n",
"max_q_value = q_values_s1[best_action]\n",
"\n",
"print(\"--- 策略改进演示 ---\")\n",
"for action, q_val in q_values_s1.items():\n",
" print(f\"动作 {action} 的价值: {q_val}\")\n",
"\n",
"print(f\"\\n=> 最佳动作是 '{best_action}',其价值为 {max_q_value}。\")\n",
"print(\"结论:只要我们在每个状态都选择 Q 值最大的动作,就能得到一个更好的、甚至是最优的策略!\")"
]
},
{
"cell_type": "markdown",
"id": "618e235d",
"metadata": {},
"source": [
"## 3. 求解 BOE:压缩映射与迭代法\n",
"BOE 看起来很难解,因为它方程两边都有未知数 $v$。但数学上的**压缩映射定理 (Contraction Mapping Theorem)** 告诉我们三个好消息:\n",
"1. **存在性**BOE 一定有解。\n",
"2. **唯一性**:最优状态价值 $v^*$ 的解是唯一的。\n",
"3. **算法**:可以通过不断迭代 $v_{k+1} = \\max_\\pi(r_\\pi + \\gamma P_\\pi v_k)$ 来逼近最优解,这个过程叫**价值迭代 (Value Iteration)**=。\n",
"\n",
"## 4. 影响最优策略的因素\n",
"* **折扣因子 $\\gamma$ 的魔力**\n",
" * $\\gamma$ 较大 (如 0.9):智能体目光长远,为了以最快速度拿到目标大奖,甚至愿意冒险穿过有惩罚的禁区。\n",
" * $\\gamma$ 较小 (如 0.5 或更小):智能体变得短视且保守,宁愿绕远路也不敢冒险。\n",
" * 此外,$\\gamma$ 天生就不鼓励“无意义的绕路”,因为绕路会让未来的奖励因折扣变得更小。\n",
"* **奖励的仿射变换不变性**:如果把所有的奖励都乘以一个正数,或者都加上一个固定的常数,算出来的最优策略**完全不会改变**。"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "41d7c569",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--- 情景 1:每走一步没有任何惩罚 (即时奖励为 0) ---\n",
"直达路径(A)的回报: 9.0\n",
"绕路路径(B)的回报: 7.290000000000001\n",
"结论:哪怕每步惩罚是 0,因为有 gamma 的折现,智能体依然知道直达路径更好!\n",
"\n",
"--- 情景 2:给每一步都增加 -1 的惩罚 (仿射变换) ---\n",
"增加惩罚后,直达路径(A)的回报: 8.00\n",
"增加惩罚后,绕路路径(B)的回报: 4.58\n",
"结论:增加统一惩罚后,直达路径(A)依然大于绕路路径(B)。相对好坏关系不变,最优策略不变。\n"
]
}
],
"source": [
"# 验证:假设两条路径,路径A直达终点(2步),路径B绕路(4步)\n",
"gamma = 0.9\n",
"target_reward = 10.0\n",
"\n",
"print(\"--- 情景 1:每走一步没有任何惩罚 (即时奖励为 0) ---\")\n",
"# 路径A: 0 + 0.9 * 10\n",
"return_path_A = 0 + (gamma ** 1) * target_reward \n",
"# 路径B: 0 + 0.9*0 + 0.9^2*0 + 0.9^3 * 10\n",
"return_path_B = 0 + 0 + 0 + (gamma ** 3) * target_reward\n",
"\n",
"print(f\"直达路径(A)的回报: {return_path_A}\")\n",
"print(f\"绕路路径(B)的回报: {return_path_B}\")\n",
"print(\"结论:哪怕每步惩罚是 0,因为有 gamma 的折现,智能体依然知道直达路径更好!\\n\")\n",
"\n",
"print(\"--- 情景 2:给每一步都增加 -1 的惩罚 (仿射变换) ---\")\n",
"# 路径A: -1 + 0.9 * (10 - 1) -> 简化理解为每步 -1,最后一步拿到目标\n",
"return_path_A_penalty = -1 + (gamma ** 1) * target_reward\n",
"# 路径B: 绕远路\n",
"return_path_B_penalty = -1 + gamma*(-1) + (gamma**2)*(-1) + (gamma**3)*target_reward\n",
"\n",
"print(f\"增加惩罚后,直达路径(A)的回报: {return_path_A_penalty:.2f}\")\n",
"print(f\"增加惩罚后,绕路路径(B)的回报: {return_path_B_penalty:.2f}\")\n",
"print(\"结论:增加统一惩罚后,直达路径(A)依然大于绕路路径(B)。相对好坏关系不变,最优策略不变。\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "413fb515",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "GymRL",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.9"
}
},
"nbformat": 4,
"nbformat_minor": 5
}