我理解MCTS背后的理论,但我的问题是,在游戏中使用蒙特卡洛方法需要从当前状态模拟游戏直到达到终止状态。为了使搜索收敛到Minimax(实际的理想移动序列),可能需要模拟数千甚至数百万次游戏。
我目前的做法是使用与普通Minimax搜索相同的移动生成函数,以及相同的移动执行函数,并在每次移动后检查是否获胜。在像国际象棋或跳棋这样的复杂游戏中(甚至在简单游戏中),这些操作非常耗费资源。
我的问题是:有没有更好的方法来实现游戏模拟以减少成本?我能否不进行完整的移动生成,并且每次不检查是否获胜?还有其他什么方法可以改善模拟时间?
回答:
不,你真的无法避免移动生成和检查终止游戏状态。如果你不生成移动,你也无法选择要执行的移动(显然这是推进模拟所必需的)。如果你不检查终止游戏状态……你的模拟将不符合合法游戏的要求,并且你会不必要地延长模拟时间。
加速移动生成
在某些游戏中,可能可以通过只生成部分移动来选择移动,而不需要生成所有移动。例如,在国际象棋中,你可以先随机选择一个要移动的棋子,然后只为该棋子生成移动,并随机选择其中一个。这样比生成所有棋子的所有合法移动,然后随机选择其中一个要快。然而,这也为你的移动选择引入了不同的偏见,你在模拟中最终执行的移动的概率分布将不同于所有合法移动的均匀分布。很难说这会是更好还是更差,但肯定是不同的。
提前结束模拟
MCTS的一个优势是它并不一定需要对非终止游戏状态进行启发式评估函数。然而,如果你愿意,你仍然可以使用一个。你可以提前结束模拟(在达到终止状态之前),然后使用启发式评估函数来评估这些状态。如果你想保持在无限处理时间下收敛到最优解的保证,你需要确保只限制在Play-out阶段的步数,而不在Selection阶段。在实践中,你通常没有无限的处理时间,所以这种区别不会有太大影响(尽管我怀疑这种区分会带来小的改进)
优化实现
当然,也可能只是简单地优化你的移动生成/终止游戏状态检查/前进函数。在没有看到你的代码的情况下,很难判断这里有多少改进空间。但是,例如,基于位板的状态表示将比 naive/直接的表示带来更高效的函数