带有a-b修剪和换位表的Minimax

时间:2018-11-19 15:18:16

标签: algorithm artificial-intelligence chess minimax alpha-beta-pruning

我正在尝试使用alpha-beta修剪 AND 换位表实现minimax算法。这是针对可能循环的吃豆人特工,因此必须特别注意。如果某个状态(游戏状态和转弯状态(吃豆人或幽灵))在转置表中,并且先前要看到的是该节点的父级(祖父母,...),则可以将其丢弃。这适用于没有a-b修剪的minimax。从以前的搜索来看,带有a-b的tt(换位表)似乎很难实现。我试图使代码尽可能清晰,它基于此伪代码Artificial Intelligence: A Modern Approach。我想通过第一种方法尽可能地保持最终结果。

我发现的每个伪代码都是以非常不同的方式定义的:

First pseudo-code; Second pseudo-code; Third pseudo-code

大多数差异看起来都是表面的。但是这些代码都没有我要寻找的结构:除以minValue和maxValue并经a-b修剪的minimax

预先感谢

请要求进一步的解释

1 个答案:

答案 0 :(得分:1)

对于高级AI优化我还是很陌生,但是我将分享我学到的东西。伪代码链接中的两个(1和3)都是Negamax,它比minimax棘手,因为它不那么直观。 Negamax在1和3中的两种不同实现方式需要不同的评估功能,这是它们不同的主要原因(更多信息请参见下文)。您发布的第二个链接是针对我之前未实现的MTD(f),但我认为仍然与Minimax和Negamax有所不同。 I believe MTD(f) is considered to be faster。最后,the only resource I have ever seen for Minimax with transposition tables is here我真的不确定它是否正确。 Negamax几乎是标准配置,如果您可以使用Minimax,则可以改用Negamax。

虽然Negamax和Minimax看起来不同,但它们实际上是在做相同的事情。 This blog post很好地描述了它们之间的关系,但没有解释它们之间的区别。我会在下面解释为什么它们不同。

在考虑与Minimax相关的几件事后,为什么minimax和negamax看起来不同,但本质上相同,所以变得更加明显了:

  • Minimax仅适用于2个玩家游戏,其中一个玩家是最大化玩家,另一个是最小玩家。井字游戏是一个简单的示例。
  • Minimax的典型评估函数是:如果X在终端状态中获胜,则返回+100;如果O在终端状态中获胜,则返回-100;平局时将返回0。
  • 请注意,得分如何彼此相反。玩家1赢得的每一个点都为玩家2失去了一个点。这是一个零和游戏。

关于Negamax的几点要点:

  • Negamax也仅适用于2个玩家的零和游戏。玩家1的每个点都等于玩家2的一个点。
  • Negamax使用的评估功能与Minimax略有不同。它要求始终从当前玩家的角度进行评估。也就是说,如果在终端状态X获胜并且轮到X,则评估应该为+100。如果它处于X获胜但轮到O的终结状态,则评估为-100。这与Minimax的期望不同(Minimax一直希望X胜利值+100)。伪代码1需要这种类型的评估功能。
  • 某些Negamax伪代码(如3中的Wikipedia文章)尝试通过使用“返回颜色×节点的启发式值”行中的颜色取反评估函数值来使用与Minimax相同的评估函数。这也可以,但是我从来没有那样做(下面链接到我的操作方式)。请注意,最小播放器的颜色值将仅为-1。我发现这种方式使周围的人更加困惑。
  • 现在描述了评估函数...请注意pseudo-code 3中的这一行“值:= max(value,-negamax(child,depth-1,-β,-α,-color))” 。请注意,总是从当前玩家的角度来看的返回值(某些评估值)是反转的。那是因为轮流交替出现,并且评估来自儿童状态,即另一位玩家的回合。 alpha和beta值也将反转。

借助Minimax,我们可以得出正面和负面的评价。借助Negamax,我们始终会创建积极的评估,然后根据需要将其转化为Nega。这是可能的,因为游戏的总和为零,玩家1的点数等于玩家2的点数。

为什么要使用Negamax?因为它更简单。第一次实施更具挑战性,但事情变得更加简洁。我还认为,对于Minimax和Negamax,需要以不同的方式(更复杂)处理换位表条目。最重要的是,其他所有人都使用它。我希望我能更好地解释为什么。

这是我发现的使用Negamax实现换位表的最佳资源(大多数伪代码并没有什么用):

  • Iterative Deepening NegaScout with alpha beta pruning and transposition tables
  • 我还使用转置表实现了香草Negamax,但是我找不到使用的资源。要将以上内容转换为香草Negamax,您只需用“ goodness = -minimax(state,depth-1,-beta,-alpha);”将第504行(以//空窗口搜索开始)替换为521。该代码块中的多余行是“侦查器”部分,该部分从狭窄的搜索alphaBeta窗口开始,并根据需要将其加宽。通常,NegaScout优于NegaMax。我可以分享我的完整资料,但我需要一些时间来准备适合发布到SO的内容。

如果由于某种原因您无法实现Negamax,请this is the only resource I have found for implementing Transposition Tables with Minimax

最后,我想扔几件事:

  • 使用转置表时,您可能需要使用Iterative Deepening,因为当时间受限制时,它会提供自然的截止时间
  • 使用转置表时,您将要考虑同构板。也就是说,您将需要考虑同一板的反射位置。示例:在井字面上评估该板XOX | --- | X--与评估X-- | --- | XOX(垂直翻转)相同。不知道这是否适用于Pacman,但如果有的话,这是一个巨大的改进。在井字游戏中,它会导致70-90%的搜索状态被带换位表刮掉。如果您想讨论,请在评论中回复。
  • 如果您使用JavaScript实现游戏,请注意,标准的Zobrist键将不起作用,因为JS二进制运算符以32位而不是64位进行操作。有几种不同的实现方式,但我建议从只是使用字符串作为{}对象中的键。
  • 如果您要搜索多人AI,则应该查看Hypermax / Max-N。 Minimax和Negamax的失败人数超过2位玩家。