如何编写多线程Alpha-Beta搜索算法?

我在尝试使用Alpha-Beta极小极大搜索算法创建一个国际象棋引擎,但代码运行速度太慢。我已经尽可能地进行了优化,但在单线程下仍然非常慢。我查看了其他引擎的源代码以了解它们是如何实现的,并且查阅了国际象棋编程维基(https://www.chessprogramming.org/Parallel_Search#Parallel_Alpha-Beta),但那些代码超出了我的理解范围,我找不到任何书面资料或代码片段。

有人能解释如何在Alpha-Beta搜索算法中高效地实现多线程吗?谢谢。


回答:

Alpha-Beta算法本质上是一个顺序算法,因为你的Alpha和Beta值在整个搜索过程中不断更新,剪枝决策基于这些值。因此,通过增加线程数量来提高速度是非常困难的,而且线程越多,收益越小。

然而,还是有几种方法可以实现,尽管大多数方法相当复杂,且随着线程数量的增加,扩展性极差。过去常用的算法是Young Brothers等待概念,这是一个相当复杂的算法,例如Stockfish几年前还在使用。然而,随着现代计算机上可用核数的增加,这种方法的扩展性非常差,代码也非常复杂。现在,大多数现代引擎使用的是所谓的Lazy SMP。这种算法几乎是最简单的,并且比其他算法扩展性更好。

在Lazy SMP中,你所要做的就是像平常一样启动搜索,只是使用多个线程。它依赖于一个工作中的转置表,通过该表线程之间进行通信。线程永远不会完全同步,这种随机性会导致每个线程探索搜索树的略有不同的部分,然后将结果保存到转置表中,供其他线程使用。当然,每个线程会重复一些工作,但这仍然比试图聪明地分割工作并减慢算法要好,尤其是在你开始增加线程数量时更是如此。

我建议你查看国际象棋编程维基,你甚至可以找到一些关于如何实现它的伪代码。https://www.chessprogramming.org/Lazy_SMP

不过,我还应该指出,如果你想要的是提高搜索深度的时间,实现多线程并不会帮你太多(在某些极端情况下甚至可能减慢速度!)。你需要的是对搜索树进行更积极的剪枝和更高效的实现(例如,没有内存分配,这样垃圾回收器就永远不需要运行,等等)。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注