创建自定义环境
将你的问题封装成符合 Gym 标准的 Python 类。
1. 通用环境模板
这是开发自定义环境的最佳实践结构。我们将核心逻辑分为:初始化、重置、步进以及独立的奖励计算。
gym_template.py
import gymnasium as gym from gymnasium import spaces class CustomEnv(gym.Env): def __init__(self): super().__init__() # 1. 定义 Action Space 和 Observation Space self.action_space = spaces.Discrete(...) self.observation_space = spaces.Box(...) def reset(self, seed=None, options=None): super().reset(seed=seed) # 2. 重置内部状态 self.state = ... return self.state, {} def step(self, action): # 3. 更新环境状态 self.state = self._update_state(action) # 4. 计算奖励 (推荐单独封装) reward = self._compute_reward(self.state) # 5. 判断结束 terminated = self._check_done(self.state) return self.state, reward, terminated, False, {} def _compute_reward(self, state): # 定义奖励函数逻辑 return 0.0
2. 模板深度拆解
1. 初始化 (__init__)
告诉 AI 这个世界的边界。智能体需要知道它的动作范围和感知范围。
def __init__(self):
# 例:只能往左(0)或往右(1)走
self.action_space = spaces.Discrete(2)
# 例:位置是 0 到 9
self.observation_space = spaces.Discrete(10)
2. 重置 (reset)
每一局游戏开始时,环境必须回到起点。必须返回初始状态。
def reset(self, seed=None):
# 必须调用 super().reset() 处理随机种子
super().reset(seed=seed)
self.pos = 0
return self.pos, {}
3. 奖励计算 (compute_reward)
这是我们新增的辅助方法。将奖励逻辑独立出来,让代码更清晰,方便后续调试。
def _compute_reward(self, state):
# 如果到达终点(9),奖励 1.0
if state == 9:
return 1.0
# 否则没有奖励,或者给一点负奖励鼓励快走
return -0.1
4. 步进 (step)
环境的主循环:更新状态 -> 计算奖励 -> 检查结束。
def step(self, action):
# 1. 更新位置
if action == 1: self.pos += 1
else: self.pos -= 1
# 2. 调用辅助方法计算奖励
reward = self._compute_reward(self.pos)
# 3. 判断是否结束
terminated = (self.pos == 9)
return self.pos, reward, terminated, False, {}
3. 实战演练:走廊游戏
🎯 场景描述
一条长度为 10 的走廊。智能体从 0 出发,目标是走到 9。每走一步扣 0.1 分(鼓励快速),走到终点得 1.0 分。
simple_corridor.py
import gymnasium as gym from gymnasium import spaces class SimpleCorridorEnv(gym.Env): def __init__(self): super().__init__() self.action_space = spaces.Discrete(2) # 0:Left, 1:Right self.observation_space = spaces.Discrete(10) # Pos: 0-9 self._pos = 0 def reset(self, seed=None, options=None): super().reset(seed=seed) self._pos = 0 return self._pos, {} def _compute_reward(self, pos): # 独立的奖励计算逻辑 if pos == 9: return 1.0 return -0.1 # Step penalty def step(self, action): # 1. 更新状态 if action == 1: self._pos = min(self._pos + 1, 9) else: self._pos = max(self._pos - 1, 0) # 2. 计算奖励 reward = self._compute_reward(self._pos) # 3. 判断结束 terminated = (self._pos == 9) return self._pos, reward, terminated, False, {} # --- 简单测试 --- if __name__ == "__main__": env = SimpleCorridorEnv() obs, _ = env.reset() print(f"Start: {obs}") # 尝试向右走一步 obs, rew, done, _, _ = env.step(1) print(f"Step Right -> Pos: {obs}, Reward: {rew}, Done: {done}")