期望窗口
发布时间:2008-11-20
点击:
来源:本站原创
录入者:Bruce Moreland
期望窗口是对迭代加深的改进。迭代加深的最简单的实现方法是这样的:
for (depth = 1; ; depth ++) {
val = AlphaBeta(depth, -INFINITY, INFINITY);
if (TimedOut()) {
break;
}
}
这里调用了一个“窗口”为正负无穷大的Alpha-Beta搜索,以假定返回值可能是很大的正数或负数。
假设下一次迭代时,搜索的值不会比上一次有太多的变动,那么就可以对以上的程序作改进,代码如下:
#define valWINDOW 50 // 【译注:valWINDOW是窗口的半宽,在国际象棋中通常是半个兵的价值。】
alpha = -INFINITY;
beta = INFINITY;
for (depth = 1; ; ) {
val = AlphaBeta(depth, alpha, beta);
if (TimedOut()) {
break;
}
if ((val <= alpha) || (val >= beta)) {
alpha = -INFINITY;
beta = INFINITY;
continue;
}
alpha = val - valWINDOW;
beta = val + valWINDOW;
depth ++;
}
这个代码有点烂,如果可能的话你可以把“continue”前面的部分改一下试试。这个思想是用前一次Alpha-Beta迭代的值来作用到这次的迭代中。大多数情况下你得到的返回值会在Alpha和Beta之间。如果没有,那么你可以尝试一个宽一些的窗口。
我的重新搜索并不那么有效,但是我相信你可以做得更好。一个很明显的思想是,如果返回值大于或等于Beta,你就扩展Beta,如果返回值小于等于Alpha,你就扩展Alpha,而不是我所做的Alpha和Beta都扩展。
搜索不稳定性的问题
这是你要小心搜索不稳定性的另一个地方。当我首次在我的国际象棋程序中加入期望窗口时,我设想如果返回值大于或等于Beta,那么重新搜索的结果就应该得到更大的值。完全错了,我的程序陷入了非常严重的故障!下面是它的代码:
alpha = -INFINITY;
beta = INFINITY;
for (depth = 1; ; ) {
val = AlphaBeta(depth, alpha, beta);
if (TimedOut()) {
break;
}
if (val <= alpha) { // 错!
alpha = -INFINITY;
beta = val + 1; // 【这行没有就对了,但效率会低很多。】
continue;
}
if (val >= beta) { // 错!
beta = INFINITY;
alpha = val - 1;
continue;
}
alpha = val - valWINDOW;
beta = val + valWINDOW;
depth++;
}
如果你能确认重新搜索会有结果,那么上面的代码会非常有效的。但是在我这里情况却是:
1. 搜索(Alpha, Beta)时高出边界;
2. 重新搜索(Beta - 1, INFINITY)时低出边界;
3. 重新搜索(-INFINITY, Alpha + 1)时高出边界;
4. 等等,等等……
无论如何你必须避免发生这种情况。
【译者研究认为,在用了后面要谈到的“主要变例搜索”以后,期望窗口就几乎没有作用了,因此很多程序都没有使用这个技术,尽管它的思想非常明显,看上去似乎可以起到好的效果。】
原文:
译者:黄晨 (webmaster@{域名已经过期})
类型:全译加译注
 关闭窗口
 打印文档
|