最大者的着法 | 最小者的着法 | 评分 |
A | C | 12 |
A | D | -2 |
B | C | 5 |
B | D | 6 |
-
最大者假设最小者会下出最好的棋,因此他知道,如果他选择着法
A,那么他的对手会回应
D,使最终评分变成
-2(即获胜
)。但是,如果最大者走的着法
B,那么他就会获胜,因为最小者的最佳着法仍然是正数
(5)。所以按照“最小
-最大”算法,最大者会选择着法
B,即使他选择
A并且最小者走错时评分还会更高。
“最小
-最大”原理有个弱点,从简单的例子中还不能明显地看出来——要检查的各种路线的数量是指数形式的,这就意味者工作量会以几何级数增长。
1. 每方有多少种可能的着法,这个数称为分枝因子
(Branch Factor),用
b表示;
2. 考虑的深度用
n表示,通常说“
n层”,
n是整数,“层”
(Ply)表示一个棋手走的一步棋。例如在上面介绍的迷拟游戏中,搜索深度是
2层。每个棋手走
1步。
例如在象棋中,通常在中局阶段分枝因子大约为
35种着法,在黑白棋中大约为
8。由于“最小
-最大”算法的复杂度是
O(bn),所以对一个局面搜索
4层就需要检查
150万条路线,这是多大的工作量!再增加上去,
5层就会把搜索树膨胀到
5000万,
6层则达到
18亿!
【原作者这里写的是
8
层
150
万、
9
层
5000
万、
10
层
18
亿,不知为何多算了
4
层。】
幸运的是,有办法能在精确度不打折扣的情况下大幅度削减工作量。
Alpha-Beta
搜索
——
让“最小-最大”法成为现实(也只是有一点点现实)
设想你在迷拟游戏中已经搜索了着法
B,结果你知道最大者在整个游戏中最高得分是
5。
现在假设你开始搜索着法
A了,并且一开始寻找的路线是
A-D,这条线路的得分是
-2。对于最大者来说,这是非常糟糕的,如果他走了
A,那么结果肯定会是
-2,因为最小者总是走得最好的。这是因为,如果
A-C比
A-D更好,那么最小者会选择
A-D,如果
A-C更坏
(比如说
-20),那么最小者就会选择这条路线。所以,没有必要再去看
A-C以及其他由
A产生的路线了——最大者必须走
B,因为到此位置的搜索已经能证明,无论如何
A是个更糟的选择。
这就是
Alpha-Beta算法的基本思想——只要你有一步好的着法,你就能淘汰其他可能导致灾难的变化,而这样的变化是很多的。如果再跟前面介绍的置换表结合起来,当不同路线的局面发生重复时可以节省下分析局面的时间,那么
Alpha-Beta就能产生无限的能量——在最好的情况下,它处理的结点数是纯粹的“最小
-最大”搜索的平方根的两倍,从
1500万可以减少到
2500。
【要说明
Alpha-Beta
搜索的结点数是死办法
(
即不用
Alpha-Beta
搜索的办法
)
的平方根的两倍那么多,可以分别计算搜索树中两种类型的结点——
Alpha
结点和
Beta
结点。
Alpha-Beta
搜索是完全搜索,如果某个结点是完全搜索的,那么这个结点称为
Alpha
结点,显然根结点是
Alpha
结点。那么
Alpha
结点的分枝又是什么呢?至少有一个
Alpha
结点,这是肯定的,最好的情况下,剩余的结点都可以产生截断,这些结点称为
Beta
结点。
Beta
结点有个特点,只要它的分枝中有一个
Alpha
结点产生作用,那么剩下的结点就没有搜索的必要了,我们还是取最好的情况,分枝中只有一个
Alpha
结点。
那么如何计算
Alpha
结点的个数呢?一个
Alpha
结点下面有
b
-
1
个
Beta
结点,每个
Beta
结点下面又有
1
个
Alpha
结点,这样深度每增加了两层结点数才扩大
b
倍,因此总的
Alpha
结点数就是
bn/2
。同样道理,
Beta
结点也这么计算,得到的结果也是
bn/2
,因此总结点数就是
2bn/2
。】
对着法排序来优化
Alpha-Beta
搜索
可是,我们如何才能达到预期的效果呢?我们是否还需要做其他事情?
的确是的。只要
Alpha-Beta搜索可以找到比其他着法好的着法,它就能对搜索树作出非常有效的裁减,这就意味着,关键在于首先搜索好的着法。当我们在搜索其他着法以前先搜索到最好的着法,那么最好的情况就发生了。然而最坏的情况,搜索着法的顺序是按评分递增的,即每次搜索到的着法都比曾经搜索的着法要好,那么这种情况下的
Alpha-Beta搜索就无法作出任何裁减,这种搜索将退化为极其浪费的“最小
-最大”搜索。
【这就是前一章的标题中写道“也只是有一点点现实”的原因。】
对搜索进行排序是相当重要的。让着法随便排列肯定不行,我们必须找到更聪明的办法。不幸的是,如果有简单的办法知道最好的着法,那还有搜索的必要吗?因此我们必须用“猜最好的着法”来对付。
有很多技术可以让着法的顺序排列成尽可能好的顺序:
1. 用评估函数对着法打分,然后排序。直觉上这会起到作用,评估函数越好,这个方法就越有效。不幸的是在象棋中它一点也不起作用,因为下个月我们将了解到,很多局面是不能准确评估的。
2. 找到在置换表中已经存在的局面,如果它的数值足够好,就会产生截断,这样就不必再进行其他搜索了。
3. 尝试特定类型的着法。例如,后被吃掉肯定是最坏的想法,所以先检查吃子的着法是行之有效的。
4. 把这个思路进行拓展,关注已经在同一层深度产生过截断的着法。“杀手启发”
(Killer Heuristic)是建立在很多着法是次序无关的基础上的。如果你的后被攻击了,不管你把
H2兵挺一格还是两格,对手都会吃掉你的后。因此,如果在搜索
H2-H3着法时,“象吃掉后”的着法会产生截断,那么在搜索
H2-H4着法时,“象吃掉后”很有可能也产生截断,当然应该首先考虑“象吃掉后”这一步。
5. 再把杀手启发拓展到历史表上。如果在前面几回合的搜索中,发现
G2-E4的着法很有效,那么很有可能现在仍然很有用
(即便原来的格子是象而现在变成了后
),因为棋盘其他位置的情况不太可能有多少变化。历史启发的的实现非常简单,只需要一个
64x64的整数数组,它可以起到很可观的效果。
现在已经谈了所有宝贵的思想,然而最有效的方法却稍稍有背于人的直觉,这个方法称为“迭代加深”
(Iterative Deepening)。
迭代加深的
Alpha-Beta
搜索
如果你正在搜索
6层的局面,那么理想的着法顺序应该由同样层数搜索的结果来产生。既然这明显是不可能做到的,那么能否用稍浅的搜索
(比如说
5层
)来代替呢?
这就是迭代加深方法背后的思想——一开始搜索
2层,用这样种搜索产生的着法顺序来搜索
3层,反复如此,直到到达规定的深度。
这个技术会受到一般人的质疑——大量的努力是重复的
(8到
10次乃至更多
),不是吗?
那么考虑一下搜索树的深度
n和分枝因子
b好了。搜索树在第
1层的结点数为
b,第
2层是
b2,第三层是
b3,等等。如果
b很大
(记住中局时在
35左右
),那么绝大多数工作量取决于最后一层。重复搜索
(n - 1)的深度其实是小事一桩,即便迭代加深一点也不起作用,它也只会多花
4%的时间
(在通常的局面上
)。
但是,它的优势是非常可观的——由浅一层搜索的结果排列得到的顺序,在层数加深时可以大幅度增加截断率。因此,迭代加深的
Alpha-Beta搜索实际上找的结点数,会比直接的
Alpha-Beta搜索的少很多。在使用置换表后,它的收效就更可观了——重复搜索浅的部分就几乎不需要时间了,因为这些结果在置换表里都有,没有必要重新计算了。
【需要指出的是,实际运用中通常只对根结点进行迭代加深,这样搜索的结点数是
1 + b +
…
+ bn
,比
bn
大不了多少。如果每个结点都用迭代加深,则需要搜索的结点数就是
(1 + b)n
,刚才提到在最好的情况下分枝因子为合理着法数的平方根,即
b
在
6
左右,而
6n
和
7n
是有很大区别的。
事实上,要在每个结点上都使用迭代加深,只要检查置换表就可以了,因为从根结点处做深一层的搜索时,除了新增加的一层结点以外,其他各层结点上都有最好的着法存储在置换表中了,这些着法应该优先考虑,绝大多数着法能产生裁剪,而不需要检查杀手表或者做产生产生。
另外,迭代加深可以大幅度提高历史表的效率,在前一次
N
层的搜索中历史表已经有相当丰富的历史着法信息了,在做
N + 1
层搜索时,这些历史信息可以让着法有更好的顺序。】
电脑下棋的风格
迭代加深的
Alpha-Beta搜索和置换表
(并且在历史表的推动下
)能让计算机对局面搜索到相当的深度,并且可以下国际象棋了。应该这么说,它的祖先“最小
-最大”算法决定了那台电脑
(曾经在世界上有惊人之举的那台电脑
【即冯
-
诺依曼的
ENIAC
】
)下棋的风格。
例如,设想电脑能对一个局面搜索
8层,通常在考虑某一步时,这种让人不解的模式会让让它战胜对手。只有少数一些看不清的、复杂的、迷惑人、超出直觉局面,才能让对手抓住一线机会取得胜利,而对于人类棋手
(甚至大师
)来说,这样的局面陷阱已经可以写到书里去了。
然而,如果电脑找到了一个导致和棋的无聊着法,它就会绕过陷阱,因为它假设对手会作出正确的应对,无论那种可能性有多小,只要电脑认为平局是最高的期望。
结果你可能会说,电脑下棋会极端谨慎,就像对手都是世界冠军一样。如果考虑到电脑算不到出人类棋手布置的陷阱那个深度,人类就会绞尽脑汁布设陷阱,让电脑犯错误。
(人类棋手会研究对手的下棋风格,如果卡斯帕罗夫有机会和深蓝下一百盘棋,他可能会找到深蓝的弱点并且打败它。但是我们不知道有没有这种可能性。
【现在看来,卡斯帕罗夫战胜深蓝是不在话下的,因为近几年他一直在和水平更高的电脑较量。】
)
下一个月
在第五部分,我们会讨论直接或改变深度的
Alpha-Beta搜索的局限。我们还会讨论如何利用一些技术,诸如空着启发
(Null-Move Heuristic)、静态搜索
(Quiescence Search)、期望搜索
(Aspiration Search)、
MTD(f)搜索,以及让深蓝名声显赫的“单步延伸”
(Singular Extensions)技术,它们会提高下棋水平。坚持住,我们快要结束了!
Franç
ois Dominic Laramé
e,
2000年
8月
原文:
http://www.gamedev.net/reference/programming/features/chess4/
译者:象棋百科全书网
(
webmaster@xqbase.com
)
类型:全译加译注