【发布时间】:2013-07-17 06:41:27
【问题描述】:
我了解杀手启发式背后的想法以及它为什么有用。我正在努力解决的是如何在 Alpha-Beta 搜索例程中实现它。特别是,如何确保只有兄弟节点的杀手动作首先被尝试?伪代码会有很大帮助。
【问题讨论】:
标签: artificial-intelligence chess alpha-beta-pruning
我了解杀手启发式背后的想法以及它为什么有用。我正在努力解决的是如何在 Alpha-Beta 搜索例程中实现它。特别是,如何确保只有兄弟节点的杀手动作首先被尝试?伪代码会有很大帮助。
【问题讨论】:
标签: artificial-intelligence chess alpha-beta-pruning
我将介绍实现。要获得兄弟节点的杀手级动作,请使用这样的方案
killerMoves[ply][slot]
其中ply 是与根的距离(不是搜索深度),slot 是您想要的杀手移动数。这确保了首先尝试兄弟节点,因为兄弟节点位于同一层。
要在获得 beta 截止时插入杀手招式,您可以将给定层的招式向右移动,可能会丢弃旧招式,然后插入新招式。通常,您不会将捕获或散列移动存储为杀手移动,因为它们是通过其他机制排序的。
for (int i = killerMoves[ply].Length - 2; i >= 0; i--)
killerMoves[ply][i + 1] = killerMoves[ply][i];
killerMoves[ply][0] = move;
现在,当您执行移动排序时(在遍历移动列表之前),您可以确定移动是否是杀手移动:
for (int slot = 0; slot < killerMoves[ply].Length; slot++) {
int killerMove = killerMoves[ply][slot];
for (int i = 0; i < movesCount; i++)
if (moves[i] == killerMove) {
// moves[i] is a killer move so move it up the list
break;
}
}
您不需要清除一层或任何类似物的杀手级动作,因为杀手级动作很可能是跨越同一层出现的一系列相似位置的好动作。
自从另一个答案提出以来,您可能不需要执行严格的测试,因为杀手启发式在理论上是合理的。你可以试验你使用的杀手动作的数量(通常是 2 或 3 个)以及它们相对于其他好动作(例如捕获)的顺序。
【讨论】:
在搜索树的许多部分中,杀手锏可能是一个很好的反驳动作。所以尝试其他位置的杀手锏可能是个好主意。
您可能对每个层有不同的杀手动作数组,并在进入 (ply) 时清除 (ply+1) 的数组,这将为您提供“仅限兄弟姐妹”的杀手。我会说“+1”偏移量类似于要调整的参数:尝试为 (ply+N) 清除数组,然后查看性能最佳的位置(我猜增加 N 会改善情况)。
顺便说一下,评估引擎的性能是一项不同的相当耗费资源的任务:通常一个引擎试图解决一个测试套件,或者两个具有不同参数的引擎正在比赛(比赛应该足够长,例如 100 场比赛) 之间确定哪个更好。
【讨论】: