基本用法

安装

安装 PettingZoo 基础库:pip install pettingzoo

这不包括所有环境系列的依赖项(某些环境在特定系统上安装可能会有问题)。

要安装某个系列的依赖项,请使用 pip install 'pettingzoo[atari]';要安装所有依赖项,请使用 pip install 'pettingzoo[all]'

我们在 Linux 和 macOS 系统上支持并维护 Python 3.9、3.10、3.11 和 3.12 版本的 PettingZoo。我们将接受与 Windows 相关的拉取请求(PRs),但不正式支持该系统。

初始化环境

在 PettingZoo 中使用环境与在 Gymnasium 中非常相似。您可以通过以下方式初始化环境:

from pettingzoo.butterfly import pistonball_v6
env = pistonball_v6.env()

环境通常在创建时通过参数高度可配置,例如:

from pettingzoo.butterfly import cooperative_pong_v5

cooperative_pong_v5.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_v5

env = cooperative_pong_v5.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_agentsagents 列表的长度。

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):重新设置环境的随机种子。在调用 seed() 之后、调用 step() 之前,必须调用 reset()

render():使用初始化时指定的渲染模式从环境中返回一个渲染帧。如果渲染模式是'rgb_array',则返回一个 numpy 数组;如果是'ansi',则返回打印的字符串。在 human 模式下无需调用 render()

close():关闭渲染窗口。

可选 API 组件

虽然基础 API 不要求,但大多数下游封装器和工具依赖于以下属性和方法,并且除了特殊情况(无法添加一个或多个)外,应将它们添加到新环境中。

possible_agents:一个列表,包含环境可能生成的所有智能体。等同于观察空间和动作空间中的智能体列表。这不能通过游戏过程或重置来改变。

max_num_agentspossible_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。执行完这个空步(vacuous step)后,该智能体将从 agents 和其他可变属性中移除。智能体生成只需将其添加到 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)