【问题标题】:Minimax with a-b prunning and transposition table带有 a-b 修剪和转置表的 Minimax
【发布时间】:2018-11-19 15:18:15
【问题描述】:

我正在尝试使用 alpha-beta 修剪 AND 转置表来实现一个极小极大算法。这是针对可能循环的 pacman 代理,因此必须特别注意这一点。如果一个状态(游戏状态和回合状态(吃豆人或幽灵))在转置表中,并且要看到的前一个是节点的父节点(祖父,...),则可以将其丢弃。这适用于没有 a-b 修剪的 minimax。从之前的搜索来看,带有 a-b 的 tt(转置表)似乎更难实现。我试图使代码尽可能清晰,它基于这个伪代码Artificial Intelligence: A Modern Approach。我希望使用第一种方法尽可能接近最终结果。

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

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

大多数差异似乎都是表面的。但是这些代码都没有我正在寻找的结构:一个 minimax 与一个 minValue 和一个 maxValue 与 a-b 修剪

提前致谢,

请询问任何进一步的解释

【问题讨论】:

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


    【解决方案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 和 negamax 看起来不同但本质上是相同的,在考虑了一些与 Minimax 相关的事情之后变得更加明显:

    • Minimax 仅适用于 2 人游戏,其中一名玩家是最大化者,另一名是最小化者。井字游戏就是一个简单的例子。
    • 如果 X 在最终状态下获胜,Minimax 的典型评估函数将返回 +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 中的维基百科文章,尝试使用与 Minimax 相同的评估函数,方法是在“返回颜色 × 节点的启发式值”这一行中使用颜色对评估函数值求反。这也有效,但我从来没有这样做过(链接到我如何在下面这样做)。请注意,最小玩家的颜色值仅为-1。我发现这种方式更加混乱。
    • 现在已经描述了评估函数...请注意pseudo-code 3 中的这一行“value := max(value, -negamax(child, depth - 1, -β, -α, -color))”。请注意,始终从当前玩家的角度来看的返回值(一些评估值)是反转的。那是因为轮流交替并且 eval 来自子状态,轮到另一个玩家。 alpha 值和 beta 值也会倒置。

    对于 Minimax,我们提出了正面和负面的评价。使用 Negamax,我们总是创建积极的评估,然后在必要时反转它们,因此 Nega。这是可能的,因为游戏是零和游戏,玩家 1 的积分就是玩家 2 的失分。

    为什么要使用 Negamax?因为它更简单。第一次实施更具挑战性,但使事情更加简洁。我也相信 Minimax 比 Negamax 需要以不同的方式处理转置表条目(更复杂)。最重要的是,其他人都使用它。我希望我能更好地解释原因。

    这是我找到的使用 Negamax 实现转置表的最佳资源(大多数伪代码并不是那么有用):

    • Iterative Deepening NegaScout with alpha beta pruning and transposition tables
    • 我还使用转置表实现了 vanilla Negamax,但我无法再找到我使用的资源。要将上述内容转换为普通 Negamax,您只需将第 504 行(以 // null 窗口搜索开头)替换为第 521 行,“goodness = -minimax(state, depth - 1, -beta, -alpha);”该代码块中的额外行是“侦察”部分,它从一个狭窄的搜索 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 名玩家失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-02
      • 2015-10-15
      相关资源
      最近更新 更多