基本用法¶
安装¶
安装 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_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)
:重新设置环境的随机种子。在调用 seed()
之后、调用 step()
之前,必须调用 reset()
。
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
。执行完这个空步(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)