Monte Carlo 树搜索在实践中是如何实现的

How is Monte Carlo Tree Search implemented in practice

我在一定程度上理解算法的工作原理。我不完全理解的是算法是如何实际上在实践中实现的。

我有兴趣了解对于相当复杂的游戏(也许是国际象棋)来说最佳方法是什么。即递归方法?异步?同时?平行线?分散式?数据结构 and/or 个数据库?

-- 我们期望在一台机器上看到什么类型的限制? (我们可以 运行 并发地跨多个内核......也许是 gpu?)

-- 如果每个分支都导致一个全新的游戏在玩,(这可能达到数百万)我们如何保持整个系统的稳定? &我们如何重用已经玩过的分支?

recursive approach? async? concurrent? parallel? distributed? data structures and/or database(s)

  • 在 MCTS 中,递归实现没有多大意义(这在其他树搜索算法中很常见,例如 minimax-based 算法),因为您总是按顺序 "through" 进行游戏从当前游戏状态(根节点)到您选择评估的游戏状态(终端游戏状态,除非您选择使用 play-out 阶段的深度限制和启发式评估函数进行 non-standard 实施).使用 while 循环的更明显的实现就很好。
  • 如果这是您第一次实施该算法,我建议您先进行 single-threaded 实施。虽然这是一种相对容易并行化的算法,但有多篇论文对此进行了阐述。您可以简单地 运行 多个并行模拟(其中模拟 = 选择 + 扩展 + 播出 + 反向传播)。您可以尝试确保在反向传播期间所有内容都得到干净更新,但您也可以简单地决定根本不使用任何锁/阻塞等,无论如何,所有模拟中已经有足够的随机性,所以如果您丢失了几次模拟的信息由于 naively-implemented 并行化,这里和那里确实不会造成太大伤害。
  • 至于数据结构,不像minimax这样的算法,你实际上确实需要显式地构建一棵树并将其存储在内存中(它是逐渐构建的,因为算法是运行ning) .因此,您需要一个具有 Nodes 的通用树数据结构,其中包含一个后继/子列表 Nodes,以及一个指向父 Node 的指针(模拟反向传播所需结果)。

What type of limits would we expect to see on a single machine? (could we run concurrently across many cores... gpu maybe?)

运行 可以跨多个内核完成(请参阅上面关于并行化的要点)。我没有看到算法的任何部分特别 well-suited 用于 GPU 实现(没有大型矩阵乘法或类似的东西),所以 GPU 不太可能有趣。

If each branch results in a completely new game being played, (this could reach the millions) how do we keep the overall system stable? & how can we reuse branches already played?

在大多数 commonly-described 实现中,算法在扩展阶段(选择阶段后遇到的第一个节点)每个 iteration/simulation 只创建一个新节点存储在内存中。在同一模拟的 play-out 阶段生成的所有其他游戏状态根本不会让任何节点存储在内存中。这可以控制内存使用情况,这意味着您的树只会相对缓慢地增长(每次模拟 1 个节点的速率)。这确实意味着您获得的 re-usage 个 previously-simulated 个分支稍微少一些,因为您不会将看到的所有内容都存储在内存中。您可以选择为扩展阶段实施不同的策略(例如,为在 play-out 阶段生成的 all 游戏状态创建新节点)。不过,如果您这样做,则必须仔细监控内存使用情况。