基本用法

安装

安装基础 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)