You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Numpy实现动态规划求解GridWorld问题的代码错误排查

3x3 GridWorld动态规划值无穷大问题排查

核心错误方向及排查步骤

1. 折扣因子γ设置违规

动态规划的收敛前提是0 ≤ γ < 1,如果把γ设为1或者大于1,只要存在非终止状态的循环移动(比如机器人在网格里来回走),值函数就会不断累加奖励,最终爆到无穷大。先检查代码里有没有定义γ,或者是不是设成了1。

2. 终止状态未锁定

(3,2)和(3,3)的状态值应该固定为-1和+1,完全不参与后续迭代更新。如果代码里还在对这两个状态做值计算,会导致错误的转移累加,甚至触发循环。

  • 确认迭代循环里是否跳过了这两个终止状态
  • 检查状态转移逻辑:进入终止状态后,是否直接返回对应奖励,不再计算后续状态值

3. 状态转移/奖励逻辑出错

  • 动作偏移逻辑混乱:比如执行上移动作时,左右偏移的概率是否正确,有没有处理边界撞墙的情况(撞墙后应该停在原位置,此时奖励通常设为0,要是没处理边界,可能出现错误的状态转移路径)
  • 奖励规则错误:如果把每步移动的奖励设为正数值,再加上γ=1,会持续累加导致值爆炸;常规GridWorld里非终止步的奖励都是0

4. 值迭代更新逻辑错误

如果用了异步更新(计算一个状态就立刻覆盖原值,再用新值算其他状态),很容易导致值函数发散。正确的做法是先把所有状态的新值都算完,再一次性替换旧值。

典型错误代码示例及修复

比如这段模拟常见问题的错误代码:

import numpy as np

grid_size = 3
V = np.zeros((grid_size+1, grid_size+1))  # 1-based索引
terminal_states = [(3,2), (3,3)]
gamma = 1.0  # 致命错误:γ必须小于1

def get_next_state(state, action):
    x, y = state
    if action == 'up':
        next_x, next_y = x-1, y
    elif action == 'down':
        next_x, next_y = x+1, y
    elif action == 'left':
        next_x, next_y = x, y-1
    elif action == 'right':
        next_x, next_y = x, y+1
    # 边界处理缺失:撞墙后直接返回原位置,但未明确奖励规则
    if next_x <1 or next_x>3 or next_y<1 or next_y>3:
        return (x,y)
    return (next_x, next_y)

while True:
    delta = 0
    for x in range(1,4):
        for y in range(1,4):
            # 未跳过终止状态,会错误更新
            v = V[x,y]
            new_v = 0
            for action in ['up','down','left','right']:
                # 偏移动作逻辑错误:上下移动的偏移应为左右,左右移动的偏移应为上下
                actions = [action, 'left', 'right']
                probs = [0.8, 0.1, 0.1]
                for a, p in zip(actions, probs):
                    next_state = get_next_state((x,y), a)
                    if next_state in terminal_states:
                        reward = 1 if next_state == (3,3) else -1
                    else:
                        reward = 0
                    new_v += p * (reward + gamma * V[next_state])
            V[x,y] = new_v
            delta = max(delta, abs(v - new_v))
    if delta < 1e-4:
        break
print(V)

修复要点

  1. 把γ改成小于1的数值,比如gamma = 0.9
  2. 迭代时跳过终止状态:在循环里加if (x,y) in terminal_states: continue
  3. 修正动作偏移逻辑:上下移动的偏移是左右,左右移动的偏移是上下
  4. 确保边界处理的奖励规则明确(撞墙奖励为0)
  5. 改用同步更新:先创建一个新的V矩阵存储新值,迭代完所有状态后再替换原V

内容的提问来源于stack exchange,提问作者Agus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 04:35:01