摘 要 机器博弈是人工智能一个传统的研究领域。本文从机器博弈的基本理论谈起,介绍了机器博弈理论和机器博弈系统的一般构成,尤其阐述了现今已存在的各种机器博弈搜索算法及其优缺点。
关键词 博弈系统 博弈搜索算法 alpha-beta搜索 最佳优先搜索
1 前言 机器博弈的研究广泛而深入。早在上世纪五十年代,就有人设想利用机器智能来实现机器与人的对弈。国内外许多知名学者和知名科研机构都曾经涉足这方面的研究,历经半个多世纪,到目前为止已经取得了许多惊人的成就。1997年IBM的“深蓝”战胜了国际象棋世界冠军卡斯帕罗夫,惊动了世界。除此之外,加拿大阿尔伯塔大学的奥赛罗程序Logistello和西洋跳棋程序Chinook也相继成为确定的、二人、零和、完备信息游戏世界冠军 [1],而西洋双陆棋这样的存在非确定因素的棋类也有了美国卡内基梅隆大学的西洋双陆琪程序BKG这样的世界冠军[1]。对围棋、中国象棋、桥牌、扑克等许多种其它种类游戏博弈的研究也正在进行中。
机器博弈的核心技术是博弈搜索算法,这也是机器博弈研究的热点。本文首先介绍机器博弈的基本理论和机器博弈系统的一般构成,然后重点讲述现存的各种博弈搜索算法。
2 机器博弈的基本思想 机器博弈的核心思想并不复杂,实际上就是对博弈树节点的估值过程和对博弈树搜索过程的结合。[7]
在博弈的任何一个中间阶段,站在博弈双方其中一方的立场上,可以构想一个博弈树。这个博弈树的根节点是当前时刻的棋局,它的儿子节点是假设再行棋一步以后的各种棋局,孙子节点是从儿子节点的棋局再行棋一步的各种棋局,以此类推,构造整棵博弈树,直到可以分出胜负的棋局。整棵的博弈树非常庞大,且不同的棋类有所不同,分支因子大的如围棋的博弈树显然要比分支因子小的如国际象棋的博弈树要大得多。
博弈程序的任务就是对博弈树进行搜索找出当前最优的一步行棋。对博弈树进行极大极小搜索,可以达到这一目的。极大极小搜索,是因为博弈双方所要达到的目的相反,一方要寻找的利益恰是一方失去的利益,所以博弈的一方总是希望下一走是儿子节点中取值最大者,而另一方恰恰相反。这便形成了极大极小过程。
当然,程序不能也没有必要做到搜索整棵博弈树的所有节点,对于一些已经确定为不佳的走步可以将以它为根节点的子树剪掉。而且,搜索也不必真地进行到分出胜负的棋局,只需要在一定深度范围内对局面进行评价即可。只有搜索空间缩小到一定程度,搜索才可以真正的进行。当搜索进行到一定深度,用局面评价机制来评价棋局,按照极大极小的原则选出最优,向上回溯,给出这一局面的父亲节点的价值评价,然后再继续向上回溯,一直到根节点,最优走步就是这样搜索出来的。
在这个过程中,最为重要的是搜索算法,高效的搜索算法可以保证用尽量少的时间和空间损耗来达到寻找高价值的走步。但是真的想要博弈程序棋力提高,还必须有一个好的局面评价机制,即估值算法作后盾。就是说,用这个估值算法评价的局面价值必须是客观的、正确的,可以确凿的评价局面的优劣以及优劣的程度。
3机器博弈系统 根据机器博弈的基本思想,可以确定一个机器博弈系统的一般构成[6]。
首先是知识表示的问题,选用一种合适的方法记录棋局。这时需要考虑在这种知识表示的数据结构之上将要进行的各种操作,知识表示应该使最经常进行的操作花费的时间和空间代价最小。
其次,根据不同的棋类的不同规则集,要有一个相应的走法产生机制。它的作用是用来产生整棵博弈树,即处于博弈树的任何一个节点位置上,应该能够运用该机制产生这个节点的所有儿子节点,也就是接下来的所有合法走步。
除了以上两个模块以外,就是博弈核心的搜索技术和与之配合的估值技术了。这四个部分相互配合运转起来,就可以实现机器博弈。
4博弈搜索 博弈搜索的基本思想已经提出半个多世纪,目前广泛研究的是确定的、二人、零和、完备信息的博弈搜索。也就是说,没有随机因素的博弈在两个人之间进行,在任何一个时刻,一方失去的利益即为另一方得到的利益,不会出现“双赢”的局面,而且在任何时刻,博弈的双方都明确的知道每一个棋子是否存在和存在于哪里。
二人、零和、完备信息的博弈搜索理论已经很系统。极大极小算法是所有搜索算法的基础。在这个基础上,目前在这一领域的算法主要有两类,一类是作为主流的深度优先的alpha-beta搜索及其系列增强算法,另一类是最佳优先的系列算法[2]。
4.1 基本搜索算法 1.极大极小值算法(Minimax Algorithm)
始终站在博弈一方的立场上给棋局估值,有利于这一方的棋局给予一个较高的价值分数,不利于这一方(有利于另一方)的给予一个较低的价值分数,双方优劣不明显的局面给予一个中间价值分数。在这一方行棋的时候,选择价值极大的儿子节点走步,另一方行棋则选择价值极小的儿子节点走步。这就是一个极大极小过程。
2.负极大值搜索(Negamax Algorithm)
在极大极小过程中,每一次进行极大或者极小的比较之前,都要对到底是要选择极大还是极小节点进行判断,1975年Knuth和Moore提出的负极大值算法旨在消除两方面的差别,使算法简洁优雅。
它的核心思想在于:父节点的值是各子节点的负数的极大值。
负极大值搜索的原理和极大极小值是搜索一样的,只是表达形式不同,并且由于它的简洁,目前已经广泛取代了极大极小值算法。
4.2 深度优先的 alpha-beta搜索及其增强算法 在极大极小搜索的过程中,存在着一定程度的数据冗余,剔除这些冗余数据,是减小搜索空间的必然做法,所采用的方法就是1975年Monroe Newborn提出的alpha-beta剪枝。
把alpha-beta剪枝应用到极大极小搜索或者负极大值搜索中,就形成了alpha-beta搜索。
alha-beta剪枝的过程是这样的,如图4-1左半部所示极大极小树的片断,节点 B 的值为 18,节点 D 的值为 16,由此可以判断节点 C 的值将小于等于 16(取极小值);而节点 A 的值为节点 Max(B,C),为 18,也就是说不再需要估节点 C的其他子节点如 E、F 的值就可以得出父节点 A 的值了。这样将节点 D 的后继兄弟节点减去称为 alpha剪枝。
图4-1右半部所示极大极小树的片断,节点 B 的估值为 8,节点 D 的估值为18,由此可以判断节点 C 的值将大于等于 18(取极大值);而节点 A 的值为节点 Min(B,C),为 8。也就是说不再需要求节点 C 的其他子节点如 E、F 的值就可以得出父节点 A 的值了。这样将节点 D 的后继兄弟节点减去称为 beta剪枝。
图4-1
alpha-beta搜索由于过程简单、容易理解、且占用空间小等优良特点被广泛应用,成为现在主流的搜索算法的基础。但是它也有缺点,即它对于节点的排列非常敏感。对于同一层上的节点,如果排列合适,剪枝效率就很高,可以使实际搜索的博弈树达到最小树。所谓最小树就是一经向下搜索,第一个节点就是要寻找的走步。可是,如果节点的排列顺序不是从最差到最好,就有可能使剪枝一直无法进行,从而实际上搜索了整棵的博弈树。
大多数alpha-beta剪枝算法都采用深度优先的搜索策略,是因为深度优先搜索较之宽度优先搜索节省存储空间,只需保存根节点到当前搜索节点的路径上的节点信息即可。
针对alpha-beta搜索的特点,有许多种增强算法被提出,这些算法有些已经被证明为是非常有效的,从而成为该领域的标准搜索算法。
下面是alpha-beta的增强算法的介绍。
渴望搜索( Aspiration Search) 在alpha-beta剪枝过程中,初始的的搜索窗口往往是从-∞(即初始的alpha值)到+∞(初始的beta值),在搜索进行中再不断缩小窗口,加大剪枝效果。
渴望搜索就是渴望从一开始就使用小的窗口,从而在搜索初起,就可以进行大量的剪枝。这个初始窗口的选定很重要,如果选择准确,即所要寻找的走步就在这个窗口内,搜索便可以继续进行。如果第一步搜索的返回值证明最佳走步大于beta值,就需要重新确定窗口。以原来的beta值为alpha值,以+∞为新的beta值重新搜索。相反如果第一步的返回值证明最佳走步小于alpha值,重新确定的窗口就是以-∞为alpha值,原来的alpha值为beta值了。
可见第一次搜索猜测的窗口非常重要,如果猜测准确,搜索时间可以大大缩短,如果不准确,这一优势就不明显了。由于渴望搜索是一种基本的搜索方法,它在和后面叙述的遍历深化结合使用的时候,就可以借助前一次深度为depth的搜索的结果来猜测当前深度为depth+1搜索的窗口了。
极小窗口搜索( Minimal Window Search) 极小窗口搜索,也被称为是主变量导向搜索(Principal Variation Search),常常简称为PVS算法或者NegaScout算法。这个算法应用非常广泛。
它的出发点是和渴望搜索大致相同的,即用极小的窗口来限制剪枝范围。它的过程是这样的:
在根节点处,假定第一个儿子节点为主变量,也就是假定它为最佳走步,对它进行完整窗口(a,b)的搜索并得到一个返回值v,对后面的儿子节点依次用极小窗口(也被称为是零窗口)(v,v+1)来进行搜索,如果搜索返回值大于零窗口,则证明这一分支亦为主变量,对它进行窗口为(v+1,b)的搜索,可是如果返回值小于零窗口,这一分支就可以忽略,因为它的最佳走步还不如已有的走步。
极小窗口搜索采用了极小的窗口,剪枝效率最高,并且只对主变量进行大窗口的搜索,所以大部分搜索动作是有效的,搜索产生的博弈树也很小。
置换表( Transposition Table) 在搜索进行中,查询所有的走步,经常会在相同的或者不同的路径上遇到相同的棋局,这样的子树就没有必要重复搜索,把子树根节点的估值、子树的最好走步和取得这个值的深度信息保存在一个称为置换表的数据结构中,下次遇到时直接运用即可。
但是,对不同的情况要区别对待。对于固定深度的搜索,如果前一次保存的子树深度小于新节点要搜索的深度,还是要进行重新的搜索以保证所取得数据的准确程度。反之,如果置换表中保存的子树信息表明,子树的深度大于或者等于当前的新节点要求的搜索深度,它的信息就可以直接运用了。
置换表增强如果和有效的alpha-beta搜索结合使用,结果就会使实际搜索的博弈树小于最小树。博弈树搜索的问题实际上是一个有向图的搜索。那些在置换表中被命中的节点,就是有向图中若干路径的交叉点。只有避免这些交点被重复搜索,搜索过程中生成的搜索树才有可能小于最小树。这也是后来证明深度优先的算法并不比最佳优先的算法差的原因之一[3]。
这个算法存在的问题是,置换表的构造,必须使对置换表的查找和插入操作不成为整个搜索的负担,才能提高效率。一般使用散列表来实现。
遍历深化( Iterative Deepening) 遍历深化是因对博弈树进行多次遍历,又不断加深其深度而得名,有人还把它称为蛮力搜索。
算法利用了alpha-beta算法对子节点排序敏感的特点。它希望通过浅层的遍历给出节点的大致排序,把这个排序作为深层遍历的启发式信息。另外,算法用时间控制遍历次数,时间一到,搜索立即停止,这也符合人类棋手的下棋特点。在关键的开局和残局,由于分支较少,也可以进行较深层次的搜索。
算法的过程是,对以当前棋局为根节点的博弈树进行深度为二的遍历,得出其儿子节点的优劣排序,接着再从根节点进行深度为三的遍历,这一次优先搜索上次遍历中得出的最优者,从而加大剪枝效果,以此类推,在进行第三次、第四次的遍历,一直达到限定时间为止。
由于这个算法的每次遍历都从根节点开始,所以有人称其为蛮力搜索,但实际上由于每次都可以优先搜索相对好的节点,导致剪枝效率增大,其实算法效率是很高的,目前这一算法也得到了广泛的认可。
历史启发搜索( History Heuristic)[4] 历史启发也是迎合alpha-beta搜索对节点排列顺序敏感的特点来提高剪枝效率的,即对节点排序,从而优先搜索好的走法。
所谓好的走法即可以引发剪枝的走法或者是其兄弟节点中最好的走法。一个这样的走法,一经遇到,就给其历史得分一个相应的增量,使其具有更高的优先被搜索的权利。
杀手启发搜索 (Killer Heuristic) 杀手启发实际上是历史启发的特例。它是把同一层中,引发剪枝最多的节点称为杀手,当下次搜索时,搜索到同一层次,如果杀手走步是合法的话,就优先搜索杀手。
MTD(f)算法 MTD(f)搜索的全称是Memory –enhanced Test Driver with f and n。它是一个较新的算法,在1995左右年由Aske Plaat等人提出。它不是单一的alpha-beta算法的增强,但也是alpha-beta算法的改进。在算法进行中多次调用了零窗口的alpha-beta搜索过程。
在算法初起,要给定一个初始值f,一个上界和一个下界。初始值要尽可能的靠近最后要找到的最优走步值,上界和下界要保证能把这个最优走步包含在内。算法实际上就是不断的应用零窗口的alpha-beta搜索,缩小上界和下界,并移动初始值使其接近最优走步。以下使这个算法的伪代码[1]。
function MTD(n, |) –〉|
g := |
|+ := +∞ ; | := -∞
repeat
if g = |- then γ:= g + 1 elseγ := g;
g := alphabeta(n,γ-1,γ)
if g < γ then |+ := g else |- := g;
until |- ≥ |+
return g;
图4-2
在这个伪代码中,可以看出算法名称中的f为初始值,而n为搜索深度,这里g为最后要找的最佳走步,γ为零窗口的上界。
由于算法运用了多次alpha-beta搜索,所以需要配合置换表,这样才能使速度足够的快,从而达到提高效率的目的。
MTD(f)算法简单并且比前述各种算法都高效。有不少实践者的实验证明,在国际象棋、西洋跳棋等博弈程序里,MTD(f)的平均表现要比PVS好,当今最强大的国际象棋程序之一,麻省理工学院的Cilkchess就使用了并行的MTD(f)代替了其初始版本的NegaScout作为搜索算法[8]。
4.3 最佳优先算法 理论上,最佳优先的搜索算法,由于不受节点排序的影响,其搜索空间小于深度优先的最小树,应该优于深度优先。所以在二十世纪六七十年代,相继有人提出了最佳优先的系列算法。但是,最佳优先算法可以说一直都待在研究人员的实验室里。真正的博弈程序开发者很少有使用这个算法的。而 Alpha-Beta经过一系列增强如置换表、历史启发、零窗探测、遍历深化等手段,其性能已远远高于最初的 Alpha-Beta。一些研究人员发现有部分基于 Alpha Beta的博弈程序实际生成的搜索树已小于最小树[3]。
最佳优先算法分为两类[5],一类是仍然采用极大极小方法取值的SSS*算法和DUAL*算法,另一类是没有采用极大极小方法取值的B*和PB*算法。
SSS*和DUAL*算法 这两种算法即为状态空间搜索(State Space Search),由Stockman在1979年提出。
它们是把极大极小树的搜索看成是对状态图的搜索,在不同的分支上展开多条路径,并且维护一个关于状态图的全局信息表。搜索过程同一般的状态图搜索大致一样,还需要维护一个有序的OPEN队列辅助。
SSS*算法和DUAL*算法是两个相对的过程,二者对最大值或最小值的操作相反,最大化操作和最小化操作相反,OPEN队列的排列的排列也是相反的。 Aske Plaat等人的研究表明SSS*算法在搜索深度为偶数的极大极小搜索中表现较佳,DUAL*则在深度为奇数搜索中较佳。
这两个算法的缺点是:算法复杂,难于理解;额外的数据结构占用空间大;并且维护有序的OPEN队列所用的时间开销大。
B*和PB*算法 1969年Berliner提出了B*算法,用一个乐观值和一个悲观值来表示评价值。算法从这点出发,用这两个界来证明哪个节点是最好的。当根节点的一个孩子的悲观值不比所有其它节点的乐观值差的时候,B*算法就结束了。算法的搜索控制就是尽可能快的得到终止条件。
B*算法的缺点是它对局面的乐观值和悲观值的估计得可信赖程度,它对这个估值的依赖性太强。
PB*算法就是基于概率的B*算法,由Paley在1983年提出。这个算法对概率的准确估计比较敏感,实现困难。
5结语 以上简明地阐述了机器博弈理论的原理,并且对现存的二人零和完备信息搜索方法给出了比较全面的讲述。二人零和完备信息博弈的研究已经有半个多世纪的历史,其知识结构系统,层次清晰,已经取得了许多惊人的成果。另一个方向是非完备信息游戏的博弈研究,本文没有涉及。这方面的研究也取得了一些成果,如拼字游戏Scrabble,桥牌和扑克,都可以实现人机对战的过程,有一些程序还相当强大,但比之完备信息的博弈,它的研究还远远不够广泛。