纸牌游戏 Crib 的动作空间应该是什么?

人工智能 强化学习 人工智能设计 开放式 环境 健身房
2021-11-15 22:02:22

我正在为纸牌游戏创建一个环境,代理选择在游戏的第一阶段丢弃某些纸牌,并使用剩余的纸牌进行游戏。(如果你熟悉的话,这个游戏就是婴儿床。)

我怎样才能为这些动作创造一个动作空间?例如,在这个游戏中,我们可以弃掉 6 张牌中的 2 张,然后从剩余的 4 张牌中选择 1 张来玩,然后从剩余的 3 张牌中选择 1 张,然后从剩余的 2 张牌中选择 1 张。我该如何建模?

我已阅读有关使用 MultiDiscrete 空间的这篇文章,但我不确定如何根据先前选择的操作来定义此空间。这甚至是正确的方法吗?

1个回答

在使用深度强化学习之前,我实际上已经实现了这个游戏。您在这里处理的是动态动作空间,其中动作空间可能会在游戏的每个时间步(或更一般地 MDP)发生变化。首先,让我们讨论 Crib(或 Cribbage)的两个阶段中的每个阶段中的实际动作空间,并将问题形式化。

阶段 1:弃牌:在这个阶段,你同时弃牌 2 张牌,不考虑顺序。因此,您有一个固定的离散动作空间大小(62)=15.

第二阶段:出牌:在这个阶段,你和你的对手依次打出你剩余的 4 张牌中的每一张(原来的 6 减去第一阶段丢弃的 2)。因此,您有一个大小为离散的动作空间4!=24. 这是一个问题 - 并非所有这些行为都是合法的。游戏的当前状态限制了您可以玩的牌(当前所有牌的总和不得大于 31)。由于您不知道对手的牌和/或策略,因此您不知道这 24 种行动中的哪一种是有效的。为了解决这个问题,行动空间应该规定在当前时间步可以打出你剩余的哪些牌因此,您在每个时间步都有一个大小为 1、2、3 或 4的动态离散动作空间。

我怎样才能为这些动作创造一个动作空间?

由于您没有指定任何实现标准(例如 OpenAI Gym),因此有多种路径可供选择,它们通常取决于您对状态特征向量的实现。在我自己的实现中,我修改了两种可能的状态表示,它们很容易描述。

可能性1:每个阶段的独立状态表示:在阶段1,你需要知道你手中的牌和分数;即,状态特征向量可以编码为一个列表[card0, card1, card2, card3, card4, card5, your score, opponent score]. 此状态代表从单个玩家的角度来看,在阶段 1 中有关游戏的所有已知信息;在每个时间步之后,当前玩家可能会发生变化,并且必须根据当前玩家的观点更新状态。每张卡片可以编码为从 1 到 52 的整数(不是从 0 开始,我们将在下一段中看到),分数是从 0 到 120 的整数(提示:对卡片进行排序以减少状态空间和更快的收敛)。你的行动空间可以是一组从 0 到 14 的整数,映射到你手中的 2 张牌组合。或者,您可以有一个动态动作空间,依次要求您丢弃 6 张牌中的 1 张,然后要求您丢弃剩余 5 张牌中的 1 张。动作空间可以是从 0 到 5 的整数子集,映射到您手中的一张牌。这里要小心——在选择要丢弃的第二张牌时,您的算法必须知道首先丢弃哪张牌。您可以通过在状态向量中添加另一个组件来解决此问题,该组件表示第一张被丢弃的卡片(在阶段开始时设置为 0),因此,请确保在第一次丢弃后更新状态。

在第二阶段,你需要知道你手上的4张牌、被砍的牌、分数以及当前打出的牌。另一个有用但不必要的学习功能是当前已玩牌的总和。一个可能的表示是一个列表[card0, card1, card2, card3, card played0, card played 1, card played 2, …, card played 7, your score, opponent score, cut card, current sum of played cards]已出牌的值应在阶段开始时初始化为 0。可以更新状态,使你手中的任何一张牌都被设置为0,而你对手打出的任何一张牌都可以被设置为负值。这将正确编码从您手中打出的牌,打出的牌是您从对手打出的,以及所有其他可用信息。因此,行动空间是动态的,是从 0 到 3 的整数子集,映射到您手中的一张牌。

可能性 2:每个阶段的相同状态表示另一种可能性是将每个阶段的所有上述信息与阶段编号一起编码为单个状态表示与阶段 1 无关的阶段 2 特有的状态特征可以在阶段 1 期间设置为 0,反之亦然。使用这种表示,状态特征向量在游戏的所有时间步长都是相同的,并且动作空间将如上所述发生变化。编码的重要思想与上面完全相同,并且会根据您的特定实现而改变,因此我不会在此处包含详细信息。

我该如何建模?

如果您要实现类似于可能性 1 的东西,那么您可能需要两个代理,每个代理都学习一个单独阶段的策略。对于初学者,您可以使用 Q-learning 或 DQN 并在每个时间步采取具有最大 q 值的动作,确保所选动作始终是当前动作空间的成员

如果你要实现类似于可能性 2 的东西,那么你可能只需要一个智能体来学习每个阶段的策略,因为阶段是状态的一个特征。本质上,您是在用更复杂的状态表示来换取更简单的学习算法。

我已经阅读了这篇关于使用 MultiDiscrete 空间的帖子,但我不确定如何根据之前选择的操作来定义这个空间。这甚至是正确的方法吗?

阅读 OpenAI Gym 文档后,看起来 MultiDiscrete 空间是 Discrete 空间的产物。因此,它是一个固定的动作空间,本质上不是您想要的(动态动作空间)。我不相信 OpenAI Gym 标准会原生支持动态动作空间。您需要做一些额外的工作,例如提供一个返回环境当前动作空间的方法。或者,如果您想遵循(state, reward, done, info)来自 OpenAI Gym 的信号范式,您可以在信息字典中提供当前动作空间。最后,另一个想法是允许智能体总是从更大的固定动作空间中选择一个动作(例如阶段 2 的 0 到 3 整数集),然后在智能体选择一个动作时通过奖励信号惩罚它不是当前行动空间的成员(例如,如果所选卡已在阶段 2 中使用)。之后,您将返回当前游戏状态作为下一个状态并让代理重试。

我的建议是首先确定状态表示,然后你的其余实现应该遵循,使用上面的想法。