自定义OpenAI Gym气球环境奖励异常求助:停止泵送时奖励为何为0?
自定义OpenAI Gym气球环境的奖励逻辑问题分析与修复
你当前的代码在模拟时,当智能体选择停止动作(action=0)时奖励为0,不符合“停止泵送时提取当前累积奖励”的预期,核心问题出在step函数的奖励逻辑和终止条件处理上。
问题定位
- 停止动作未设置正确奖励:当action=0(停止泵送)时,代码仅设置了
terminated=True,未赋予当前累积的奖励值,导致这一步奖励为初始的self.reward(0)。 - 冗余的reward初始化:
step开头的reward = self.reward完全多余,你的奖励逻辑基于当前泵送次数动态计算,无需依赖这个实例变量。 - burst函数隐含风险:从输出看三次泵送后气球未破裂,需确认
burst函数逻辑是否正确(比如是否在npumps >= max_pump时返回True)。
修正后的核心代码
def step(self, action): assert self.action_space.contains(action) terminated = False reward = 0 if action: # 执行泵送动作(1) self.npumps += 1 if burst(self.max_pump, self.npumps): self.balloon = 1 terminated = True reward = 0 # 气球破裂,奖励清零 else: reward = self.npumps # 泵送成功,奖励累积当前次数 else: # 执行停止动作(0) terminated = True reward = self.npumps # 停止时提取当前累积奖励 if self.render_mode == "human": self.render() return self._get_obs(), reward, terminated, False, {} def reset(self, seed=None, options=None): super().reset(seed=seed) self.npumps = 0 self.balloon = 0 # 1表示破裂,0表示正常 # 移除多余的self.reward变量,不再使用 return self._get_obs(), {}
关键修正说明
- 停止动作时,将
reward设置为当前self.npumps,满足“提取累积奖励”的需求。 - 移除
self.reward实例变量,避免不必要的状态维护。 - 明确初始化
terminated和reward的默认值,逻辑更清晰。 - 确保每个动作分支都有明确的奖励赋值,避免意外的0值。
修正后预期输出示例(假设第三次泵送后选择停止动作):
{'kth pump': 1, 'balloon': 0} 1 1 {'kth pump': 2, 'balloon': 0} 1 2 {'kth pump': 3, 'balloon': 0} 1 3 {'kth pump': 3, 'balloon': 0} 0 3
内容的提问来源于stack exchange,提问作者Bong
相关产品推荐
相关产品推荐

