想象你是一位游泳池设计师,要为一座天然泳池制作一张“安全行动地图”:泳池里每个位置的深度、水温、暗流都不一样,游泳者游到不同位置需要做不同动作(加速、转弯、回岸)。问题在于——水是连续的,任意两个位置之间还能再插一个位置,状态有无穷多个。而你的地图只能画在有限的格子里(这就是Q表的本质)。怎么把“无限的连续状态”压缩成“有限的格子”,让每个位置都能查到该做什么动作?这就是状态离散化要解决的问题。 本文用“给泳池铺瓷砖”这个比喻贯穿始终:分箱离散化像用标准瓷砖均匀铺满池底;聚类离散化像马赛克,按水深分布铺出疏密;瓦片编码则像铺两层半透明交错瓷砖,让每个位置同时有多层描述。最后我们会讨论瓷砖该选多大、如何评估铺法好不好。

岗位关联

学通状态离散化,你才能让 Q 表这类经典算法真正落地到机器人、游戏和工业控制等连续环境,也为理解 DQN 等深度强化学习的“连续状态编码”打下直觉基础。

目录
  1. 可视化演示
  2. 连续状态挑战
  3. 离散化核心原理
  4. 分箱离散化
  5. 聚类离散化
  6. 瓦片编码
  7. 离散粒度权衡
  8. 效果评估实践
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示均匀分箱、聚类自适应分箱和Tile Coding多层覆盖三种连续状态离散化方法,通过网格划分、聚类中心和层叠瓦片直观理解Q表构建原理。

本节配有交互动效(进入视口后自动加载,约 3KB)。

均匀分箱离散化 将连续状态空间等间隔划分为网格,每个格子对应一个Q值 s→bin(s)→Q[bin(s),a] 连续状态点被映射到最近的离散格子,Q值在格子间跳跃变化

连续状态挑战

泳池里的水是连续的:从这头游到那头,水深和暗流是逐渐变化的,两个点之间永远能再找一个中间点。真实环境中智能体看到的“状态”也是这样——小车的位置、速度、水温、压力,都是连续变化的实数,理论上有无穷多个取值。

在强化学习中,状态是智能体观测到的环境信息。以经典的小车爬山任务为例,状态就是 (位置 x, 速度 v) 这两个连续量。Q表是什么呢?它是一张“在某个状态下做某个动作值多少钱”的查找表,只能按编号去索引。如果直接拿连续状态去查表,你会发现表里根本没有这一行——因为连续状态是无穷多个,你不可能造一张无穷大的表。

就像泳池里每一滴水的位置都不同,无法为每滴水单独写一条行动指示。想让“安全行动地图”可用,必须先决定“把多少水归为同一块瓷砖”——这就是离散化的起点。我们无法直接解决无穷,但可以把无穷折叠成有限。

S=[xmin⁡,xmax⁡]×[vmin⁡,vmax⁡]⊂R2\mathcal{S} = [x_{\min}, x_{\max}] \times [v_{\min}, v_{\max}] \subset \mathbb{R}^2
这个公式说明:位置和速度各自在一个区间内自由取值,两者组合起来构成一个二维的连续状态空间,里面的点有无穷多个,无法逐一写进 Q 表。
  1. 状态变量用小写字母 \(x\) 表示位置、\(v\) 表示速度,它们是互相独立的两个观测量:
    S=[xmin⁡,xmax⁡]×[vmin⁡,vmax⁡]\mathcal{S} = [x_{\min}, x_{\max}] \times [v_{\min}, v_{\max}]
  2. 区间约束\(x_{\min}\) 和 \(x_{\max}\) 是位置的下界与上界,状态不会超出这个范围:
    x∈[xmin⁡,xmax⁡]x \in [x_{\min}, x_{\max}]
  3. 连续实数域\(\mathbb{R}^2\) 表示状态取值为实数对,数量和实数一样多,无法枚举:
    S⊂R2\mathcal{S} \subset \mathbb{R}^2

离散化核心原理

铺瓷砖的关键不在瓷砖本身,而在“划分规则”:只要确定规则,泳池里任何一个点,都能立刻告诉你它落在哪块瓷砖上。离散化做的正是这件事——它构造一个映射函数 \(\phi\),把连续状态变成有限个编号之一。

有了编号,Q表立刻就能用了。原来更新公式里的连续状态,全部换成编号;学习时遇到一个新状态,先算它属于哪个格子,再查表、更新表。

离散化还带来一个隐藏好处:原本相近的连续状态被分进同一个格子,它们的经验可以互相“借用”,学习速度因此加快——这就像泳池地图上,同块瓷砖覆盖的区域共用同一条行动建议。设计离散化方案时,有三个旋钮要拧:格子总数、格子边界画在哪、状态按什么规则归入格子。后面三种方法正是这三个旋钮的不同拧法。

Q(ϕ(s),a)←Q(ϕ(s),a)+α[r+γmax⁡a′Q(ϕ(s′),a′)−Q(ϕ(s),a)]Q(\phi(s), a) \leftarrow Q(\phi(s), a) + \alpha \left[ r + \gamma \max_{a'} Q(\phi(s'), a') - Q(\phi(s), a) \right]
这是 Q-Learning 的核心更新公式:用“当前奖励 + 未来收益的最大估计”减去旧估计得到误差,再按学习率 \(\alpha\) 修正。关键是所有状态都先经过 \(\phi\) 变成格子编号。
  1. 离散映射\(\phi\) 把连续状态 \(s\) 映射成 \(\{1,2,\dots,N\}\) 中的一个编号,Q表只能索引这类编号:
    ϕ:Rd→{1,2,…,N}\phi: \mathbb{R}^d \to \{1, 2, \dots, N\}
  2. 时序差分误差方括号中的内容是“现实值减去估计值”,\(r\) 是本步奖励,\(\gamma\) 是折扣因子,\(\max_{a'}\) 表示对下一个状态的每个动作取最大 Q 值:
    r+γmax⁡a′Q(ϕ(s′),a′)−Q(ϕ(s),a)r + \gamma \max_{a'} Q(\phi(s'), a') - Q(\phi(s), a)
  3. 步长更新\(\alpha\) 是学习率,控制每次朝误差方向修正多少,避免一步走太远:
    Q(ϕ(s),a)←Q(ϕ(s),a)+α⋅TD误差Q(\phi(s), a) \leftarrow Q(\phi(s), a) + \alpha \cdot \text{TD误差}

分箱离散化

最省事的铺法来了——标准瓷砖,全部一样大,横平竖直排满池底。分箱离散化就是这样:把位置范围 \([x_{\min}, x_{\max}]\) 平均切成 \(K\) 段,速度范围也切 \(K\) 段,二维就得到 \(K \times K\) 个格子。任何一个状态,看它在每维落到第几段,就得到了二维坐标,再压成一维编号。

分箱的优点是简单、可解释、好调试,很多入门项目都够用;缺点也很明显:所有维度独立等分,如果状态分布不均匀,大部分格子根本没样本访问,白白浪费。泳池如果大部分地方浅而平、只有一小块深不见底,用标准瓷砖铺,深水区一块砖管太大、浅水区又太浪费——这时候就该让数据说话,引出聚类。

Δx=xmax⁡−xmin⁡K,ϕ(x)=⌊x−xmin⁡Δx⌋\Delta x = \frac{x_{\max} - x_{\min}}{K}, \qquad \phi(x) = \left\lfloor \frac{x - x_{\min}}{\Delta x} \right\rfloor
第一行算每格宽度,第二行把状态 \(x\) 映射成它所在格子的编号。速度维度同样处理,两个编号合起来就是一个格子索引。
  1. 箱体宽度把区间等分成 \(K\) 段,每段宽度为 \(\Delta x\),段数越多单价越窄:
    Δx=xmax⁡−xmin⁡K\Delta x = \frac{x_{\max} - x_{\min}}{K}
  2. 向下取整\(\lfloor \cdot \rfloor\) 表示取不超过内部数值的最大整数,保证编号落在 \(0\) 到 \(K-1\):
    ⌊x−xmin⁡Δx⌋\left\lfloor \frac{x - x_{\min}}{\Delta x} \right\rfloor
  3. 二维合并位置和速度各得到一个编号,组合成唯一格子:
    ϕ(s)=[ϕ(x),ϕ(v)]\phi(s) = [\phi(x), \phi(v)]

聚类离散化

马赛克砖的铺法:深水区用小砖精细铺,浅水区用大砖粗略铺。但“哪里算深、哪里算浅”怎么定?让数据自己说。聚类离散化先让智能体在环境里随机跑一段,采集大量真实状态样本,然后把这些样本聚成 \(K\) 簇,每簇的“质心”就代表一块瓷砖的锚点。

聚类的好处是自适应:状态密集的区域自动分得细,稀疏区域分得粗,格子数量总等于 \(K\),不会像分箱那样均匀浪费。它的代价是依赖采样质量——如果采集的样本没覆盖某个区域,那个区域划分就不可靠。马赛克虽然精美,但工匠必须亲眼看过泳池每个角落,才能拼出好图案。

ci=1∣Ci∣∑s∈Cis,ϕ(s)=arg⁡min⁡i∥s−ci∥2c_i = \frac{1}{|C_i|} \sum_{s \in C_i} s, \qquad \phi(s) = \arg\min_i \| s - c_i \|_2
质心 \(c_i\) 是第 \(i\) 簇所有样本的平均位置;新状态来时,计算它到每个质心的欧氏距离,归入最近的那个簇,簇号就是格子编号。
  1. 质心定义\(c_i\) 等于第 \(i\) 簇内所有样本的平均,它是这簇状态的“代表性中心”:
    ci=1∣Ci∣∑s∈Cisc_i = \frac{1}{|C_i|} \sum_{s \in C_i} s
  2. 欧氏距离\(\| s - c_i \|_2\) 计算状态与质心的直线距离,距离越小越“像”这个簇:
    ∥s−ci∥2=∑j(sj−ci,j)2\| s - c_i \|_2 = \sqrt{\sum_{j}(s_j - c_{i,j})^2}
  3. 最近邻归入\(\arg\min\) 表示挑选距离最小的那个簇的编号,作为状态的格子编号:
    ϕ(s)=arg⁡min⁡i∥s−ci∥2\phi(s) = \arg\min_i \| s - c_i \|_2

瓦片编码

现在试试另一种铺法:先铺一层标准瓷砖,再错开半块砖的位置铺第二层半透明瓷砖。于是泳池里任何一个点,同时被两层各一块瓷砖覆盖——“这位置既有'深水层'的信号,又有'水温层'的信号”。瓦片编码(tile coding)就是这样:用多张网格(tiling),每张网格都做均匀分箱,但每张的起始偏移量不同。

瓦片编码的精髓是“重叠带来泛化”:因为每层网格都错开一点,两个相近的状态会共享大部分被激活的瓦片,它们的 Q 值也就自然地互相影响。好比两滴水在同一层可能落进不同瓷砖,但在另一层却落进同一块——多层描述让“相似”被显式刻画。专业泳池师傅都爱这种铺法:多层错缝,任何位置都能同时从多个尺度被描述。

ϕj(s)=⌊s+δjΔ⌋,ϕ(s)=[ϕ1(s),ϕ2(s),…,ϕT(s)]\phi_j(s) = \left\lfloor \frac{s + \delta_j}{\Delta} \right\rfloor, \qquad \phi(s) = [\phi_1(s), \phi_2(s), \dots, \phi_T(s)]
第 \(j\) 层用偏移量 \(\delta_j\) 错开切分,状态在第 \(j\) 层激活一块瓦片;总共 \(T\) 层就激活 \(T\) 块瓦片,这些瓦片编号拼成一个特征向量。
  1. 单层瓦片第 \(j\) 层的分箱公式和均匀分箱类似,只是分子上加了一个偏移 \(\delta_j\),让网格错开:
    ϕj(s)=⌊s+δjΔ⌋\phi_j(s) = \left\lfloor \frac{s + \delta_j}{\Delta} \right\rfloor
  2. 层内激活在每一层里,状态只落入一块瓦片,这块瓦片的编号就是本层给出的“描述”:
    ϕj(s)∈{1,2,…,N}\phi_j(s) \in \{1, 2, \dots, N\}
  3. 多层叠加把 \(T\) 层的编号拼成向量,不同层激活不同位置的瓦片,构成重叠互补的特征表示:
    ϕ(s)=[ϕ1(s),ϕ2(s),…,ϕT(s)]\phi(s) = [\phi_1(s), \phi_2(s), \dots, \phi_T(s)]

离散粒度权衡

瓷砖到底选多大?这是所有铺法绕不开的问题。瓷砖太大,深水区被一刀切,地图失去指导意义;瓷砖太小,数量爆炸,每块瓷砖被踩到的机会太少,游泳者的经验根本喂不饱每块砖。在强化学习里,这被称为“偏置—方差”权衡:粗粒度偏置大,策略上限低;细粒度方差大,估计抖动、训练不稳。

还有一个更残酷的数学事实:离散格数会随维度爆炸。假设状态有 \(d\) 个维度,每维切 \(K\) 份,总格数是 \(K^d\)。每个格子都需要积累足够样本,收敛所需样本量随格子数线性增长——维度一多,均匀分箱立刻吃不消。

好泳池不是砖越小越好,而是砖的尺寸与泳池的形状、水流分布相匹配。实操中的经验是:低维(1~2 维)可以放心用细分箱;维度稍高就优先考虑聚类或瓦片编码;实在不确定时,先用粗粒度跑通流程,再逐步加密观察收益是否还划算。

Ncells=∏i=1dKiN_{\text{cells}} = \prod_{i=1}^{d} K_i
总格子数是每个维度分箱数的乘积。只要维度稍微升高,格子数量就呈指数级增长,这是“维度灾难”的典型表现。
  1. 单维格数第 \(i\) 个维度被切成 \(K_i\) 份,代表这个维度上的分辨率:
    Ki (i=1,2,…,d)K_i \ (i = 1, 2, \dots, d)
  2. 笛卡尔积总状态数是所有维格数的乘积,维数越多乘积爆炸得越快:
    Ncells=∏i=1dKiN_{\text{cells}} = \prod_{i=1}^{d} K_i
  3. 收敛代价每个格子都需要足够多的访问样本,收敛所需样本正比于格子总数:
    T收敛∝NcellsT_{\text{收敛}} \propto N_{\text{cells}}

效果评估实践

砖铺得好不好,不看砖本身,看游泳者能否又快又稳地游到终点。评估离散化方案同样要看两个东西:策略质量和收敛速度。策略质量用累计回报来衡量——从起点出发,按学习到的策略走完一个回合,把每一步的奖励按折扣累加,得到 \(J(\pi)\),越大越好。

实践中建议这样操作:第一步,把状态各维度归一化到 \([0,1]\),避免量纲差异干扰分箱;第二步,从粗粒度(每维 10~20 格)开始训练,观察回合奖励曲线;第三步,如果曲线上升太慢或平台期太低,再加密或换用瓦片编码(常用 4~8 层)。记得同时记录不同方案的收敛曲线——粗粒度往往前期涨得快但封顶低,细粒度前期磨蹭但后劲足,两者的交叉点就是权衡的生动写照。毕竟,泳池铺得再漂亮,游不到终点也是白搭。

J(π)=Eπ[∑t=0Tγtrt]J(\pi) = \mathbb{E}_{\pi} \left[ \sum_{t=0}^{T} \gamma^{t} r_t \right]
这是在策略 \(\pi\) 下多次试验的平均累计回报。它把随机性抹平,给出一个稳定分数,用来横向对比不同离散化方案。
  1. 累计回报把每个时刻的奖励 \(r_t\) 按折扣 \(\gamma^t\) 累加起来,\(T\) 是回合长度:
    ∑t=0Tγtrt\sum_{t=0}^{T} \gamma^{t} r_t
  2. 期望算子\(\mathbb{E}_{\pi}\) 表示在策略 \(\pi\) 下做多次试验再取平均,消除随机性:
    Eπ[⋅]\mathbb{E}_{\pi}[\cdot]
  3. 质量指标\(J(\pi)\) 越高代表学到策略越好,是所有离散化方案对比的最终标尺:
    J(π)=Eπ[∑t=0Tγtrt]J(\pi) = \mathbb{E}_{\pi} \left[ \sum_{t=0}^{T} \gamma^{t} r_t \right]

AI 应用场景

移动机器人避障导航

阶段:状态空间设计(特征工程)

解决的问题:机器人激光雷达返回的是连续距离值,手工设置避障规则很难覆盖各种场景。用分箱离散化把“距离+角度”连续观测切成格子,Q表直接查询当前格子对应的最佳转向动作,实现实时反应式避障。

具体案例:某扫地机器人项目把前方障碍距离分成 20 段、角度分成 18 档,得到 360 个离散状态,配合 6 个动作训练 Q 表。在仿真房间中训练 300 回合后,碰撞次数下降约 80%,清扫覆盖率明显提升。

游戏AI平衡控制

阶段:特征表示

解决的问题:CartPole(倒立摆)这类游戏环境,观测是连续的位置、速度、角度和角速度。均匀分箱需要大量格子且收敛慢;用瓦片编码把连续观测编码成稀疏特征,让 Q 学习在几百回合内就学会稳定平衡。

具体案例:在 CartPole 上使用 4 层、每层 8×8 的瓦片编码,约 300 回合达到 500 步满分;而使用 256 格均匀分箱需要 1000 回合以上。同样的观测,换一种离散化方式,训练效率天差地别。

工业过程控制

阶段:离线数据分析 + 策略训练

解决的问题:反应釜的温度、压力传感器数据连续且分布极不均匀——平稳工况占大多数,剧烈波动只占少数。均匀分箱会在平稳段浪费大量格子。先用 K-means 对历史工况聚类,让平稳段和剧烈段各自获得合适的粒度,再训练 Q 表给出阀门调节策略。

具体案例:某化工恒温控制项目中,用 K=32 的聚类离散化配合 Q 表控制加热功率,温度超调量比固定参数 PID 降低约 30%,且对工况变化更鲁棒。

Python 演示

python75 行
"""分箱离散化 + Q-Learning 小车爬山(简化版Mountain Car)"""import mathimport random  class MountainCar:    def __init__(self):        self.pos = -0.5        self.vel = 0.0        self.min_pos, self.max_pos = -1.2, 0.6        self.max_vel = 0.07        self.bins_pos = 20        self.bins_vel = 20     def reset(self):        self.pos, self.vel = -0.5, 0.0        return self.discretize()     def discretize(self):        p = int((self.pos - self.min_pos) / (self.max_pos - self.min_pos) * self.bins_pos)        v = int((self.vel + self.max_vel) / (2 * self.max_vel) * self.bins_vel)        p = min(self.bins_pos - 1, max(0, p))        v = min(self.bins_vel - 1, max(0, v))        return p * self.bins_vel + v     def step(self, action):        force = action - 1        self.vel += force * 0.001 + math.cos(3 * self.pos) * (-0.0025)        self.vel = max(-self.max_vel, min(self.max_vel, self.vel))        self.pos += self.vel        done = False        if self.pos <= self.min_pos:            self.pos, self.vel = self.min_pos, 0.0        if self.pos >= 0.6:            done = True        return self.discretize(), -1.0, done  class Agent:    def __init__(self, n_states, n_actions=3):        self.q = [[0.0] * n_actions for _ in range(n_states)]        self.alpha = 0.2        self.gamma = 0.95        self.eps = 0.1     def choose(self, s):        if random.random() < self.eps:            return random.randrange(3)        return max(range(3), key=lambda a: self.q[s][a])     def learn(self, s, a, r, s2):        td = r + self.gamma * max(self.q[s2]) - self.q[s][a]        self.q[s][a] += self.alpha * td  def main():    env = MountainCar()    agent = Agent(env.bins_pos * env.bins_vel)    for episode in range(300):        s = env.reset()        total = 0        for _ in range(300):            a = agent.choose(s)            s2, r, done = env.step(a)            agent.learn(s, a, r, s2)            s = s2            total += r            if done:                break        if episode % 50 == 0:            print("episode", episode, "reward", total)  if __name__ == "__main__":    main()
目的:演示如何把连续的位置、速度状态用均匀分箱映射成格子编号,再驱动 Q 表学习爬山策略——这是“连续状态空间离散化”在代码层面的最小可运行示例。
  1. p = int((self.pos - self.min_pos) / (self.max_pos - self.min_pos) * self.bins_pos)把连续位置按比例映射到格子下标
  2. return p * self.bins_vel + v把位置的格子号和速度的格子号合并成一维索引,方便查表
  3. td = r + self.gamma * max(self.q[s2]) - self.q[s][a]计算时序差分误差:现实估计减去旧估计
  4. self.q[s][a] += self.alpha * td按学习率把误差修正到 Q 表对应条目
  5. a = agent.choose(s)用 \(\varepsilon\)-贪心策略在“探索随机动作”和“利用当前 Q 表”之间做选择

常见误区

误区我只要把分箱数调大,格子够小,状态描述得足够精确,Q表就一定能学到更好的策略。

正解粒度变细会让每个格子分到的样本变少,Q 值估计的方差增大,训练反而出现震荡甚至不收敛。最优粒度在“偏置—方差”的平衡点附近,而不是越细越好。就像瓷砖越小,每块砖被踩到的次数越少,经验根本喂不饱它们。

为何常见:直觉上“精确描述 = 更好”,但忽略了统计学习中样本量是有限的,精度提升需要样本量来买单。

误区位置和速度都是状态,切成一样的格子数最省事,反正维度平权。

正解不同维度的重要性、量纲差异很大。位置范围大但是平缓变化,速度或许更关键;应该先归一化各维度,再根据重要性分配格子数——就像深水区和浅水区不应该用同样大小的瓷砖。

为何常见:均匀分箱实现最简单,新手很容易默认所有维度天然等价。

误区K 值设得越大,聚类切得越细,Q 表一定越准确。

正解K 越大,每个簇的样本越少,质心估计越不稳定;聚类质量还依赖采样分布,覆盖不足的区域会产生误导性划分。K 需要根据状态分布和可用样本量来选择,不是越大越好。

为何常见:把“簇数量”直接和“精度”划等号,忽略了聚类本身也是统计估计,样本不足时同样会方差爆炸。

误区只要把连续状态离散化,Q-Learning 就一定收敛到最优策略。

正解离散化只是第一步。收敛还依赖学习率 \(\alpha\)、折扣因子 \(\gamma\)、探索率 \(\varepsilon\) 和奖励设计;如果离散映射破坏了关键状态的区别,策略最优性也会受损。地图画得再细,游泳者不听指挥也到不了终点。

为何常见:教科书例子通常直接给出离散状态,让人误以为环境处理是自动完成的。

误区瓦片编码不就是把几张均匀网格画在一起嘛,跟单层分箱没有本质区别。

正解瓦片编码的关键是“错位偏移 + 多分辨率叠加”:不同层在不同位置激活,状态被编码成一组互补的粗粒度局部特征,Q 值是被激活瓦片权重的线性组合。这是一种特征泛化机制,与单层分箱有本质差别——就像两层错缝的透明瓷砖,能同时告诉你“这里有深水”和“这里有水草”。

为何常见:只看到“网格”的表象,忽略了偏移与叠加带来的表示能力变化。

面试题

Q1. 关于连续状态空间,以下说法正确的是?

单选题 · easy

  • A.连续状态只包含少数几个离散取值
  • B.真实环境的状态经常是连续变化的实数← 正确答案
  • C.Q表可以直接存储连续的状态空间
  • D.连续状态不需要处理就能查表更新

答案:B。真实环境中的位置、速度等观测通常是连续实数,数量无穷多,Q 表只能索引离散条目,因此必须先做离散化。A 错在“少数几个”,C、D 都忽略了 Q 表的离散索引限制。

Q2. Q表为什么无法直接处理连续状态?

单选题 · easy

  • A.连续状态数量无穷多,无法建满整个表← 正确答案
  • B.连续状态的数值都太小,无法计算
  • C.连续状态一定是高维的矩阵形式
  • D.Q表只能存储离散的整数动作

答案:A。Q 表的大小等于“状态数 × 动作数”,连续状态有无穷多个,表无法建完也无法索引。B 与数值大小无关,C 表述片面,D 混淆了“状态离散”与“动作离散”两个概念。

Q3. 均匀分箱中,状态 \(x\) 的格子编号公式是?

单选题 · mid

  • A.\(\phi(x) = \lfloor (x - x_{\min}) / \Delta x \rfloor\)← 正确答案
  • B.\(\phi(x) = \lceil (x_{\max} - x) / \Delta x \rceil\)
  • C.\(\phi(x) = (x - x_{\max}) \cdot \Delta x + x_{\min}\)
  • D.\(\phi(x) = \lfloor (x_{\max} - x) \cdot \Delta x \rfloor\)

答案:A。分箱先把 \(x\) 相对下界 \(x_{\min}\) 的距离除以箱宽 \(\Delta x\),再向下取整得到编号。B 用了上取整且方向反了,C 的运算量纲不对,D 把区间上界代入也会导致编号方向颠倒。

Q4. 分箱数 K 过大会带来什么主要问题?

单选题 · mid

  • A.每个格子样本稀疏,Q估计方差变大← 正确答案
  • B.状态空间变小,信息反而大量丢失
  • C.奖励函数的数值会变得不稳定
  • D.Q表的存储空间一定会变小

答案:A。K 过大时格子总数暴增,每个格子被访问的次数减少,Q 值估计方差增大、训练不稳。B 描述的是 K 过小的问题,C 与奖励函数无关,D 恰好说反——格子变多存储变大。

Q5. K-means 聚类离散化中,状态被划分给?

单选题 · easy

  • A.与状态欧氏距离最近的质心← 正确答案
  • B.与状态欧氏距离最远的质心
  • C.包含样本数量最多的质心
  • D.随机选择的任意一个质心

答案:A。聚类离散化把状态归入欧氏距离最近的质心所在簇,簇号即格子编号,这是 K-means 的最近邻分配规则。B、C、D 都不符合 K-means 的分配逻辑。

Q6. 瓦片编码中,一个状态会激活多少块瓦片?

单选题 · hard

  • A.每层一块,T 层共激活 T 块← 正确答案
  • B.所有层的瓦片全部被激活
  • C.只激活离它最近的一块瓦片
  • D.激活数量由状态数值大小决定

答案:A。瓦片编码有 T 层网格,每层网格中状态只落入一块瓦片,因此总共激活 T 块瓦片,这是它获得重叠特征的基础。B 显然错误,C 描述的是单层情况,D 与瓦片结构无关。

Q7. 关于离散粒度与收敛速度,正确的是?

单选题 · mid

  • A.粒度越细,算法收敛一定越快
  • B.粗粒度收敛快但策略质量上限低← 正确答案
  • C.粒度对收敛速度没有任何影响
  • D.粒度只影响奖励值的大小

答案:B。粗粒度格子少,每个格子样本充足,收敛快但偏置大、策略上限低;细粒度表达力强但样本稀疏,收敛慢。A 说反了,C、D 否定粒度作用都不成立。

Q8. 以下哪些属于状态离散化方法?

多选题 · mid

  • A.均匀分箱方法← 正确答案
  • B.K均值聚类方法← 正确答案
  • C.瓦片编码方法← 正确答案
  • D.反向传播方法

答案:ABC。均匀分箱、K-means 聚类、瓦片编码都是把连续状态映射到有限格子的离散化方法。反向传播是训练神经网络参数的方法,不属于状态离散化。

Q9. 关于粗粒度与细粒度的对比,正确的有?

多选题 · hard

  • A.粗粒度格子少,训练更快← 正确答案
  • B.细粒度表达力强,上限更高← 正确答案
  • C.细粒度需要更多样本才能稳定← 正确答案
  • D.粗粒度一定比细粒度效果好

答案:ABC。粗粒度格子少、样本集中、训练快;细粒度状态更精确、理论上限高,但样本被稀释、更容易不稳定。D 说“一定更好”过于绝对,实际要看任务和样本量。

Q10. 瓦片编码相比均匀分箱,优势体现在?

多选题 · extreme

  • A.一次更新影响多块瓦片← 正确答案
  • B.重叠特征带来自然泛化← 正确答案
  • C.状态间相似度被显式刻画← 正确答案
  • D.不需要设置每层网格数目

答案:ABC。瓦片编码中一个状态激活多块瓦片,一次 Q 更新会让多块瓦片同时修正;相邻状态共享大部分瓦片,相似度被重叠结构显式表达,这是其泛化能力的来源。D 错误——每层网格数目仍然需要人工设置。