基本用法¶
安装¶
安装基础 PettingZoo 库:pip install pettingzoo
。
这不包括所有环境系列的依赖项(某些环境在特定系统上安装可能存在问题)。
要安装某个环境系列的依赖项,请使用 pip install 'pettingzoo[atari]'
,或使用 pip install 'pettingzoo[all]'
安装所有依赖项。
我们在 Linux 和 macOS 系统上支持并维护 PettingZoo,兼容 Python 3.9, 3.10, 3.11 和 3.12。我们会接受与 Windows 相关的 PR,但不提供官方支持。
初始化环境¶
在 PettingZoo 中使用环境与在 Gymnasium 中使用非常相似。你可以通过以下方式初始化环境:
from pettingzoo.butterfly import pistonball_v6
env = pistonball_v6.env()
环境通常在创建时通过参数高度可配置,例如:
from pettingzoo.butterfly import cooperative_pong_v6
cooperative_pong_v6.env(ball_speed=18, left_paddle_speed=25,
right_paddle_speed=25, cake_paddle=True, max_cycles=900, bounce_randomness=False)
与环境交互¶
可以使用类似于 Gymnasium 的接口与环境交互
from pettingzoo.butterfly import cooperative_pong_v6
env = cooperative_pong_v6.env(render_mode="human")
env.reset(seed=42)
for agent in env.agent_iter():
observation, reward, termination, truncation, info = env.last()
if termination or truncation:
action = None
else:
# this is where you would insert your policy
action = env.action_space(agent).sample()
env.step(action)
env.close()
常用的方法有
agent_iter(max_iter=2**63)
返回一个迭代器,该迭代器产生环境中的当前智能体。当环境中的所有智能体完成或达到 max_iter
(步骤执行完毕)时,迭代器终止。
last(observe=True)
返回当前可以行动的智能体的观察、奖励、完成状态和信息。返回的奖励是智能体自上次行动以来获得的累计奖励。如果 observe
设置为 False,则不会计算观察,而是返回 None。请注意,单个智能体完成并不意味着环境完成。
reset()
重置环境并在首次调用时进行设置以便使用。此方法必须在调用任何其他方法之前调用。
step(action)
接受并执行智能体在环境中的动作,自动将控制权切换到下一个智能体。
附加环境 API¶
PettingZoo 将博弈建模为 智能体环境循环 (AEC) 博弈,因此可以支持多智能体强化学习可以考虑的任何博弈,这允许处理非常奇怪的情况。因此,我们的 API 包含了一些较低级别的函数和属性,你可能不常需要它们,但在需要时它们非常重要。不过,它们的功能也用于实现上述高级函数,因此包含它们只是代码重构的问题。
agents
:所有当前智能体名称的列表,通常是整数。这些名称可能随着环境的进程而改变(即可以添加或移除智能体)。
num_agents
:agents 列表的长度。
agent_selection
:环境中对应当前选定的智能体(可以为其采取动作)的属性。
observation_space(agent)
:一个函数,用于检索特定智能体的观察空间。对于特定的智能体 ID,此空间永远不应改变。
action_space(agent)
:一个函数,用于检索特定智能体的动作空间。对于特定的智能体 ID,此空间永远不应改变。
terminations
:调用时所有当前智能体终止状态的字典,按名称作为键。 last()
访问此属性。请注意,可以从该字典中添加或移除智能体。返回的字典看起来像
terminations = {0:[第一个智能体的终止状态], 1:[第二个智能体的终止状态] ... n-1:[第 n 个智能体的终止状态]}
truncations
:调用时所有当前智能体截断状态的字典,按名称作为键。 last()
访问此属性。请注意,可以从该字典中添加或移除智能体。返回的字典看起来像
truncations = {0:[第一个智能体的截断状态], 1:[第二个智能体的截断状态] ... n-1:[第 n 个智能体的截断状态]}
infos
:每个当前智能体信息的字典,按名称作为键。每个智能体的信息也是一个字典。请注意,可以从该属性中添加或移除智能体。 last()
访问此属性。返回的字典看起来像
infos = {0:[第一个智能体的信息], 1:[第二个智能体的信息] ... n-1:[第 n 个智能体的信息]}
observe(agent)
:返回智能体当前可以进行的观察。 last()
调用此函数。
rewards
:调用时所有当前智能体奖励的字典,按名称作为键。奖励是上次步骤后生成的瞬时奖励。请注意,可以从该属性中添加或移除智能体。 last()
不直接访问此属性,而是将返回的奖励存储在内部变量中。奖励结构看起来像
{0:[第一个智能体的奖励], 1:[第二个智能体的奖励] ... n-1:[第 n 个智能体的奖励]}
seed(seed=None)
:重新设置环境种子。 reset()
必须在 seed()
之后、step()
之前调用。
render()
:使用初始化时指定的渲染模式从环境中返回一个渲染帧。如果渲染模式是'rgb_array'
,则返回一个 numpy 数组;如果是 'ansi'
,则返回打印的字符串。在 human
模式下无需调用 render()
。
close()
:关闭渲染窗口。
可选 API 组件¶
虽然基础 API 不要求,但大多数下游封装器和工具依赖于以下属性和方法,除非在特殊情况下无法添加一个或多个,否则应将其添加到新环境中。
possible_agents
:环境可能生成的所有可能的智能体列表。等同于观察空间和动作空间中的智能体列表。此列表不能通过游玩或重置来更改。
max_num_agents
:possible_agents 列表的长度。
observation_spaces
:每个智能体观察空间的字典,按名称作为键。此空间不能通过游玩或重置来更改。
action_spaces
:每个智能体动作空间的字典,按名称作为键。此空间不能通过游玩或重置来更改。
state()
:返回环境当前状态的全局观察。并非所有环境都支持此功能。
state_space
:环境全局观察的空间。并非所有环境都支持此功能。
常用模式¶
检查整个环境是否完成¶
当智能体终止或截断时,它会从 agents
中移除,因此当环境完成时,agents
将是一个空列表。这意味着 not env.agents
是检查环境是否完成的简单条件。
解封装环境¶
如果你有一个被封装的环境,并且想要获取其下方所有封装层下的原始环境(以便手动调用函数或更改环境的底层方面),你可以使用 .unwrapped
属性。如果环境已经是基础环境,.unwrapped
属性将返回自身。
from pettingzoo.butterfly import knights_archers_zombies_v10
base_env = knights_archers_zombies_v10.env().unwrapped
可变数量的智能体(死亡)¶
智能体可以在环境过程中死亡和生成。如果一个智能体死亡,其在 terminated
字典中的条目将被设置为 True
,它将成为下一个被选择的智能体(或者在另一个已终止或截断的智能体之后),并且它必须采取的动作是 None
。在执行完这个空动作后,该智能体将从 agents
和其他可变属性中移除。智能体生成只需将其添加到 agents
和其他可变属性中(前提是它已在 possible_agents 和动作/观察空间中),并在某个时刻使用 agent_iter 转换到它。
将环境视为智能体¶
在某些情况下,将智能体和环境动作分开有助于研究。这可以通过将环境视为智能体来完成。我们建议在 env.agents 中将环境执行者命名为 env
,并让其采取 None
作为动作。
原始环境¶
环境默认被封装在一些轻量级封装器中,这些封装器处理错误消息并确保在不正确使用(例如进行非法移动或在重置前进行步骤)时表现合理。然而,这些会增加极少量开销。如果你想创建不带这些封装器的环境,可以使用每个模块中包含的 raw_env()
构造函数来实现
environment_parameters = {} # any parameters to pass to the environment
env = knights_archers_zombies_v10.raw_env(**environment_parameters)