残局库是经特别算法产生的特定格式的、储存各限定棋子数目的残局之所有局面及其估值的数据库文件集合。概述地说,残局数据库是储存了残局局面并经回溯分析计算过的数据库文件,它使用在棋弈程序上,当进入残局时,只要适合使用的残局数据库文件存在,程序将走得非常完美。 多数棋弈引擎并不一定要到达残局库所涵盖的局面时才使用残局库。例如,在到达如此局面之前几步,引擎计算(但还没走棋)一系列交换之后直接进入残局库里存有的局面。引擎于是搜索探查残局库并取得那个设想局面的结果。如此当然提高了棋力。
在残局库的开发方面,Ken Thompson仍然是先导者。80年代期间,他开始制作4子和5子的残局库。一个典型的5子残局如:王双象对王单马,就包含有121,000,000种不同的局面。如果再加一个兵,那么局面数会增加到335,000,000。为此,Thompson专门编写了程序,用于生成所有可能的局面并计算出每一个强制性的变化。然后他又通过某种方式将计算数据压缩,使得一张标准的CD-ROM上可以存放20个不同的残局。
残局库格式是多种多样的,包括肯·托普森式(Ken Thompson)、史蒂文·爱德华兹式(Steven J. Edwards)、欧根尼·纳利莫夫式(Eugene Nalimov)以及Chessmaster9000专用的EDGB残局库格式。 不过总的来说它们划分为两种残局库类型:将杀步数(DTM)类型和变换步数(DTC)类型。粗略地以非专业语言来说,彼此之间区别如下: 将杀步数(DTM)类型:即Distance to mate,这种类型的库为每一个局面储存最短的将杀可能(以层,即ply来计算,一层相当于半个回合)。例如Nalimov残局库。 变换步数(DTC)类型:即Distance to conversion,这种类型的库储存每一个局面及其一个“转换”之间的最短层数。所谓一个转换,指或者是兵升变,或者某子被吃去,或者出现将杀。例如Thompson残局库。 另外,无论是DTM还是DTC类型的残局库,都不能识别50回合自然限着规则。为了克服它们的缺点,已经提出了DTZ和DTR另外两种类型。但至今只停留在理论上。 说到具体每种格式的区别,还不能简单就说得清楚的。Crafty的作者于2000年10月在新闻组作过如下解释: “Edwards式:属于将杀步数(DTM)类型。Edwards式的主要问题是这种残局库体积比其它的庞大。 “Nalimov式:也属于将杀步数(DTM)类型,但Nalimov式的残局库文件是压缩的,也可以以压缩形式使用而无不利之处。对于拥有全部3、4、5子残局的残局库,别的格式其文件总数大小超过30G,而使用这种格式的大约只有7.5G。 “Thompson式:属于变换步数(DTC)类型(每当发生吃子,残局的‘级数’都变小)。这种格式难以以压缩形式使用,相对于Nalimov式,它提供的信息也不相同……比如,它告诉你一些信息,却没有区分是负还是和,而Nalimov式对此则有区分。 “Nalimov式是最佳选择。几乎每个引擎都支持它……” 当然,他没有提及仅是Chessmaster9000专用的EDGB格式残局库,因为EDGB是2002年8月才发布的。Nalimov式仍然是最流行的在用残局库格式,因此我想再多谈一点这种格式。 Nalimov式几近“完美”,因为它把吃过路兵也考虑进去了。但是没把王车易位也考虑进去。只不过,大概只有排局迷才会对此计较。 总的来说,现代几乎所有的国际象棋程序包括大多数Winboard引擎使用Nalimov式残局库,一部分原因是它们不设版权,一部分原因它们更高效。现在Nalimov式残局库已经出了部分6子残局库。Nalimov式残局库有两种形式,压缩的和非压缩的,压缩的以“emd”为文件后缀。 多数现代棋弈程序能解压使用压缩的残局库,例如Crafty从16.5版本后就支持压缩的Nalimov式残局库。我注意到有个Winboard引擎Esc只能用非压缩的。 残局库还有其它一些格式,但比较少见。比较著名的,商业性高级棋弈软件Nimzo8使用它的Nimzo残局库,这种残局库放入到内存中使用,因此读取比较快。一直没有公开发表但棋力不俗的Ferret也使用它的专用残局库。我文章余下部分,除非特别说明,残局库都是指Nalimov式。
残局库是通过特定算法生成的满足某一子力条件的全部局面的胜负和判定信息,一般也包括在区分胜负时距离将死或吃子最近的步数的信息。
原理:后退式算法。以炮兵单士象对士象全为例说明如何生成。以下的文字只阐述残局库算法的最一般的原理和思想,不能保证细节上与现存的各残局库计算程序的代码完全吻合。
1 将全部的炮兵单士象(红)对士象全(黑)的局面以及可能由炮兵士象全对士象全的局面通过吃子得到的局面编号,区分红先黑先。
2 标识出以上局面中,黑方被将死或者困毙的局面。
3 选择出轮红走,可以形成2中局面的局面,称为红一步胜局面。
4 从轮黑走的余下的(指不包含2中局面)局面中选择出无论走哪一步下一步均会进入红一步胜局面的局面,称为黑两步负的局面。
5 从轮红走的余下的局面(指不包含3)中选择出能够保证下一步进入黑两步负的局面,称为红三步胜局面。
6 从轮黑走的余下的局面中(指不包含2、4)选择出无论走哪一步下一步均会进入红三步胜的局面,称为黑四步负局面。
.
2k+3 从轮红走的余下的局面中选择出能够保证下一步进入黑2k步负的局面,称为红2k+1步胜局面。
2k+4 从轮黑走的余下的局面中选择出无论走哪一步下一步均会进入红2k+1步胜的局面,称为黑2k+2步负局面。
如此下去,由于总的局面数有限,一定会出现某一步,以上的步骤不再生成新的局面。那么以上的全部局面则是全部的红先必胜,黑先必败的局面。其余的局面均为和棋。
实际上,由于存在吃子关系,大多数残局库一般都是由较少子力往上生成的而不是直接按照以上的步骤一次性生成可能存在若干次吃子的残局库。我们一般首先算子力较少时的残局库,然后往上增加子力。在生成子力较多的残局库时可以利用子数较少的残局库。如生成炮兵士象对士象全的残局库时,首先需要选出炮兵士象及士象全都在盘面上时的将死及困毙的局面,以及可能通过一次吃子进入的必胜必败局面,即由炮兵士象对士象全局面,红通过一次吃子,进入的炮兵士象对单缺士等的黑必败的局面(已经算好并储存在相应的残局库),或者黑无法避免通过一次吃子,形成炮或者兵士象对士象全的红必胜的局面(已经算好并储存在相应的残局库)。然后运用上面所述的倒推的算法将全部的必胜必败的局面算出。显然,这里面直接算出的步子是局面转化的步子,而不是直接距离将死的步骤。这样的计算较为经济节省。但是缺点也很明显,无法直接说出某个红(或黑)必胜的局面距离将死的步数,只能说出距离吃子最近的步数。有时候二者还是有区别的。
另外,中国象棋存在一个复杂的因素,即禁止长将长捉等等循环的攻击性着法。以上的残局库算法不能考虑到这一点,必须进行修正。对于亚洲棋规来讲相对还比较简单,先按照以上的步骤生成允许长将长捉的残局库。然后标识出红或者黑可以进行长将的局面。从中选取变招则进入必败的局面。然后向后递推,直到不能生成新的局面。将以上的局面标记成order=1的红胜或负的局面。然后从长将的局面中选取出,变招则进入order=1的局面的的局面,继续后推,直到封闭,生成order=2的局面。如此向后,直到穷尽全部的长将长捉的局面。那么余下的全部局面就是亚规的真正的和棋局面。当然,这样的算法导致步数的计算十分复杂,是残局库有时候不能正确给出距离吃子最近乃至距离将死最近的招法的根源。但是,关于胜负和的信息依然是绝对正确的。而中国棋规就过于复杂,目前基本不能在残局库层面实现。
残局库和棋软的区别,为何残局库能够计算出某些长达几百步的胜局而棋软不行。
通过残局库计算出长达几百步的胜局,乃是中国象棋和国际象棋共有的情况。由于残局库算法的科学性,这些结论是不需要被质疑的。但是有人会问,为强机强棋软都很难在残局局面算超过50步,残局库怎么可能在双核机上算出200步的胜局?根源还是在算法的根本不同。残局库的计算量主要取决于局面总数,一般来说类似于炮兵士象全对士象全的残局,局面总数即使是极度粗糙的包含大量冗余的估算,也就10^10数量级。而棋软的计算主要是向后遍历博弈树,计算量主要取决于分支数和回合数。还是这个残局,一个回合的变化数大致在150至200(炮兵方20左右,士象全方7-10)上下。那么要是穷举计算仅仅10回合的全部变化就已经在10^21量级,可以说是大大高于残局库的计算复杂度,即使是现有的棋软都有非常有效的裁剪,基本上也很难支撑100步以上,更何况裁剪在这种情况下往往是有害的。这也是为什么强软强机也不能算出数百回合的必胜,而残局库算法在弱机上就能算出来的原因。
现有残局库能够算出哪些残局,算不出哪些。
一般来说64G内存能够在可容忍的时间内算出的残局局面能够复杂到车兵对马炮双士这样的量级。这个残局库的大小已经有4.6G。 像马炮全对马全这样的残局,乃至局面总数更多的,所需的内存已经达到3800多G,短期内是不能被算出来的。大多数江湖残局的主体局面都是目前不能被残局库解决的。如大征西的主体局面车炮兵对车炮相,要3800多G内存,带子入朝的主体局面车卒象对车双兵士,需要2700G内存。显然它们在可预见的时间入残局库的可能性是零。
然而,残局库依然解决了不少靠人力难以解决的深度惊人的实用残局。如炮高兵单士象必胜士象全就是个著名例子。只是由于亚规允许一将一捉等,导致不少有车残局算出的和局存在着劣势方实负的可能,但是算出的必胜是绝对正确的。
参考资料
https://tieba.baidu.com/p/3463112599?red_tag=1810576185
https://baike.baidu.com/item/%E6%AE%8B%E5%B1%80%E5%BA%93/8728859?fr=aladdin
http://www.zgxqds.com/blog/article.asp?id=24031