百科狗-知识改变命运!
--

象棋软件引擎分析,详细信息,引擎是怎么搜索招式的?

一语惊醒梦中人1年前 (2023-12-20)阅读数 6#综合百科
文章标签节点知识

作者:nicepeople10

中象棋软搜索引擎揭密(一) fenon

北京大赛终于过去了, 在这场盛事前后这段时间, 静下心来回顾了走过的象棋研究的路子,心得感触良多.为了纪念这段时间的美好, 我决定把这段时间积累的对象棋引擎的心得, 总结分享出来

我个人希望通过这篇文章,把一些顶尖棋软的知识普及开来,提高开源象棋软件的水平.

1. 搜索引擎和审局之间的关系, 如何建立

阅读下面的内容时, 首先需要了解几个背景知识

a. 人工智能的博弈搜索树和PVS搜索之间的关系

b. PVS搜索是无损搜索

c. PVS的搜索效率和搜索次序的关系

首先明确几点:

a. 做一个全PVS的搜索, 在限定了层数的情况下, 如果基于不正确的知识(比如子力表),并不能保证一定能把杀棋找出来(可能会跑去吃子)

b. 为了提高棋力, 无损搜索PVS是不足够的, 还是需要剪枝的

c. 搜索树和审局之间的关系, 首先知识必须能够引导搜索到正确盘面(这个地球人应该都知道), 第二是避免搜索把正确的分支剪除掉(这个谈论得少一些,我以前曾经有很长一段时间不知道)

我认为, 审局和搜索之间的关系的建立, 在于

a. 知识是带有正确的倾向性的(只能说是倾向性,因为知识很难做到全面准确)

b. 搜索是根据知识而采取剪枝方式的(这个下面详细分析)

下面我举一个简单的例子, 来说明知识和搜索之间的关系

_____

| | |

马 _| 将_|_兵

象棋软件引擎分析,详细信息,引擎是怎么搜索招式的?

| _ |_ |_ |_象

在这个盘面, 兵只要靠近王一步, 就可以将死了对方, 但是基于子力表做depth=1的PVS搜索,只会选择: 兵吃象, 有利, 而且评估子力分数很高, 所以吃象

那么, 有什么办法避免这种情况呢?

a. depth=1的时候不做剪枝

b. 给予引擎审局的知识, 告诉引擎保持"马非底线兵"这种组合对将才具有杀伤力

这样就给出了两种选择, 哪种更好?

实际上, b这种选择有两种局限

a. 局限于现在对审局模型建立的水平, b这种情况需要花费大量的人力功夫来维护完整的知识, 而且很难做到准确

b. 目前的引擎的搜索棋步排序, 大都是基于最近访问->杀棋步->吃子步这样的棋步排序方法, 我们可以很容易想象到, 使用全面复杂的知识, 会引起搜索结果冲突(凑着一个吃子或者杀棋的步子去走, 但是最后发现达不到预期的效果), 大大降低了搜索的效率

正是因为上面的原因, 现在我所了解到的高端引擎, 大都是通过控制剪枝的危险程度, 来弥补知识的不足, 比如, 在nullmove中限制depth>=2, 或者, 在lmr(late move reduction)--如变种:fruit的history pruning, 控制depth>=3, 都是利用控制剪枝来弥补知识的缺陷.

我们很清楚知道, depth3的棋步, 准确度是相当低甚至会引起大量错误的, 所以我们对盘面评估会有一定的限度,同理,评估depth=1变化内的盘面,我们可以做到非常精确,这个时候可以给一个准确的分数

上面提到的a,b,c,d四种知识,对中国象棋软件的知识覆盖面是相当广了, 我们可以很简单看出, a可以奖励>马炮的分数, 而b因为可能走入误区, 常常只是奖励>士相的分数, 子力组合不会产生误区,但是需要搜索很深才能得出正解,所以分数也是不会太高,位置分则更小了

但是, 给予引擎全面而准确的知识是否恰当呢? 即, 知识是不是越全面, 棋力越强呢? 很多朋友都问过这个问题, 并且认为恰当的知识会减少搜索量, 而且这也是很多朋友追求的方向. 我实践的答案是否. 搜索其实是追求一种性价比, 单位搜索量内, 能得到最好的搜索结果, 才是好的搜索. 简单说说原理, 当盘面有两三个知识倾向都可以产生PV路径的时候, 只会带来引擎的左右徘徊, 尤其在杀棋的盘面, 会大大降低搜索的效率, 这部分的实践结果, 我会在"6. 建立以kingsafety为核心的审局, 以及审局模型的详细分析"再进一步详细分析

这里我想纠正一个错误的想法,常常有一些不了解搜索引擎原理的朋友,拿一些盘面,让棋软去判断,看谁能更快更准找到正解,要尽快解出这种盘面,往往需要大量的模糊知识,或者足够的深度,前者无疑是把棋软送上绝路的一种做法.这种评估只是有一定的意义,但绝对不是衡量棋软水平的标准.

2. fruit引擎分析, fruit引擎能达到2600的高度的原因 (对比crafty进行阐述)

fruit引擎并不追求速度,实际上,fruit并没有使用流行的bitfile,bitrank技术或者bitboard,所以fruit的nps在国际象棋引擎中并不算高(我想比起crafty应该比不上),如果说两者的差异在于评估的话,嗯,那不在我所了解的范围,我只谈谈两者引擎上面的差别

a. fruit的pv节点的意义以及基于pv节点搜索剪枝的效率

能够在搜索中, 把PV节点区分出来, 并且根据节点类型进行剪枝, fruit可以说对PVS理解是非常深刻的.

PV节点的定义大家可以查查相关资料, 既然PV节点表示正确的搜索结果, 那么就肯定不应该剪掉. 同样,对于不是PV节点的, 就不会找出正确的搜索路径, 这就应该剪掉.这个也是fruit剪枝的理论依据。

道理是这样说, 但是我们一开始并不知道每一个节点的类型, 所以在搜索的时候, 会假设某个节点不是PV节点, 然后看它是否会fail, 如果fail,再做PV节点的搜索.

假如这种假设是成立的, 那么就成功完成了对该非PV节点路径的剪枝,否则,需要重新搜索,因为对PV节点假设判断的搜索是做windows=1的搜索,所以耗费的代价是很低的.

下面来看看fruit的实现方法,我认为fruit对PV节点理解的实现方法非常优雅.

int search_root()

{

本节点做PV搜索

if (树根节点并且首节点)

下一层节点为PV节点 // 这个时候还没有找出PV路径,所以必须做PV节点搜索

else

{

下一层节点做假设不是PV节点的搜索

if (fail)

下一层节点做PV节点的搜索

}

}

int search_full()

{

根据上一层对该节点的判断, 进行节点搜索

if (首节点 || 假设不是PV节点的搜索) // 当假设不是PV节点时, windows=1这个时候不应该假设,应该直接计算了,否则就是重复计算浪费时间

下一节点的节点类型跟本节点类型一致

else

{

下一层节点做假设不是PV节点的搜索

if (fail)

下一层节点做PV节点的搜索

}

}

中象棋软搜索引擎揭密(二) fenon

crafty中,对PV节点的区分方法,是PV节点是否落在[-vMate,+vMate]中,实际上,这种判断方法,对子树的PV节点并不能做出有效的判断,这也直接导致了搜索效率的下降

正是因为PV节点的特殊意义,所以凡是PV节点,fruit都不做剪枝,不从HASH取步,甚至PV节点还需要加强搜索的强度(参考TogaII)

b. fruit的nullmove剖析

我们先来看看fruit的nullmove的实现

if (UseNull && depth >= NullDepth && node_type != NodePV) { // 不对PV节点进行剪枝, 而且depth==1时不剪枝(原因参考上文)

if (!in_check // 不是将军盘面

&& !value_is_mate(beta) // 当落入一个不知道上限的窗口时,不剪枝,这种情况发生在height==2时

&& do_null(board) // 国象规矩限定子>=2

&& (!UseNullEval || depth = beta)) { // 根据距离叶子或者alpha,beta搜索中,棋形的评估进行控制

我想, 对上面的控制条件,大家都是很好理解的, fruit中NullRedcution==3, 这个可以理解为fruit审局做得比较完善,depth4时候剪枝的控制条件,这种控制条件往往是根据棋形进行控制, crafty是控制大子的个数, fruit是控制评估的结果, 考虑到这个结果因引擎而异, 我就不在这里讨论哪种条件才是更好的了

new_depth = depth - NullReduction - 1;

move_do_null(board,undo);

value = -full_search(board,-beta,-beta+1,new_depth,height+1,new_pv,NODE_OPP(node_type));

move_undo_null(board,undo);

fruit的nullmove会导致一种和以外不同的搜索情况产生,crafty的做法是,上一层做了NULLMOVE,现在轮到我了,我应该移动棋步,但是fruit的做法,会引起双方的等待,这是否正确?

答案是,很正确.首先,考虑算法上面的等价性,连续做NULLMOVE,其实等价于我不知道你是否做了NULLMOVE,不过我也尝试做一个NULLMOVE,看你是否能对我造成威胁,这个并不违背NULLMOVE的思想,而且一个不会产生PV路径的节点,做搜索有意义吗?没有意义.既然如此,那么就剪掉吧.

对nullmove的结果,fruit有两种特别的处理手段

第一,不保存结果,因为fruit的算法的剪枝,会让实际的值和nullmove产生的值差别很大

第二,对某些特殊情况,fruit会做一个nullmove verify的search, fruit尝试全面利用nullmove, 但是某些情况, nullmove成功的概率有限, 需要做一定的验证

fruit对nullmove的实现方法,可以说得上是历史性的(开源的引擎来说),这个算法的优异,是fruit搜索效率特高的一个根本原因

c. fruit的qs加强

在上文中, 我已经提过, fruit是尝试通过控制depth吃子步->etc,这样就很好地把杀棋和吃子都结合起来了

5. fruit算法和象眼的差异, 如何提高象眼的棋力

通过本篇的介绍, 希望能够把开源的象眼程序, 改进到一个全新的高度, 假如有人希望一起完成象眼的改进, 请站内和我联系

下面是我认为可以有效提高象眼棋力的几个地方

a. 基于PV节点的nullmove pruning

b. qs加强

c. History pruning及TogaII剪枝法

d. 棋步排序

e. hash的改进

f. IID算法修正

g.search root move list

6. 建立以kingsafety为核心的审局, 以及审局模型的详细介绍

a. 对盘面区分阶段, 不同阶段采取的策略是不同的, 开中残差异是很大的

实际上, 开局通过开局库和子力位置分+若干简单知识, 是很容易走出正确的棋步盘面的, 这个研究不深, 我更多是依赖开局库解决这个问题

残局时候, 调整位置分表, 判断子力组合, 这个时候因为子力很少, 基本上难以进取, 更多是应该考虑防守, 控制搜索的危险程度和给予适当的分数, 很容易做到这点

中局是比较复杂的, 下面详细说说我所理解的地方

b. 对某个阶段的知识, 不要给引擎太多的选择, 避免引擎找出多个PV路径, 引起棋步的来回选择, 如中局, 应该集中思考杀棋或者扩大子力的优势

c. 上面1.讲述了搜索和知识之间的关系, 其中也提及了depth=1时候的杀棋知识评估的重要性, 但是, 只是局限于depth=1的杀棋知识, 我们的盘面判断力还是很有限的, 这个时候怎么办? 我们能不能对depth>=2的情况进行评估

我提供一个实践的方法, 那就是分层次打分.

比如: 三子归边的判断, 我们通过以下三种层次评分

(a) 有沉底炮, +分 (depth=3)

(b) 有沉底炮和车可做炮架, +分 (depth=2)

(c) 有沉底炮和车并且马进入了可以助攻的区域, +分 (depth=1)

刚才在上面的审局和搜索的关系中,我列举了4种知识,并且强调了知识只应该选择有效的,下面分别说说哪些知识是必须的,不在下面列表内的知识,我都不做判断了

a. 准确的杀型

利用位置分值提示车马兵攻击王周围,依赖搜索完成

b. 模糊的杀型

(a) 当头炮 (空头炮,镇中)

(b) 底炮 (三子归边)

(c) 双车杀

c. 子力组合,只做会引起问题的子力组合判断,如兑子后双马不佳

d. 某些特别容易出问题的知识的补充

7. 国际象棋Rybka的胜利以及将来棋软发展的一些展望

一些未来的研究方向, 所以个人的意见应该是一些胡言乱语,仅作笑料

上面所说的一切, 都是基于知识会有一个确定的分数, 但是, 这明显是错误的, 谁能说三子归边是400分,而不是395分呢? 有没有一种方法, 可以动态评估这个分数, 从而达到知识的最优化呢?

第二,传说中的根据知识排序棋步的方法

在国外流行的认为Rybka超越其他软件的原因是因为更聪明的搜索和知识, 从作者言论和Rybka反映的信息做一个猜测(nps超低, 搜索准确度超高), 一致认为Rybka在搜索和评估中, 都采取了全新的方法

其中一个流派3moves现在被认为是Rybka最有可能采取的方法(包含了我的理解补充)

什么是3moves? 首先, 当前盘面移动一步, 对可以攻击的子,计算3步内可以攻击的点集,这个点集每个点都有权重.那么,多个攻击子做交集的时候, 密度最高权重最高的区域, 就是当前盘面最容易攻击的位置, 这表明了这一个棋步的攻击能力

当这个棋步能攻击到王或者其他子时, 这自然就是一个好的棋步,这时候根据点集的情况进行算分,自然是非常准确的.

这种方法超越了子力表和知识分数的局限, 而且更好理解了棋规, 也难怪被认为是最有可能的

以上转载,不知是否你想要的?

PARKER派克柱塞泵、派克油泵、派克齿轮泵、派克叶片泵在 深圳港丰行科技 提供:

PARKER派克柱塞泵购买须知:

派克PARKER油泵的特点:

1、Parker派克PAV6.3和PAV10系列轴向柱塞泵为斜盘式变量柱塞泵,用于开式回路。单泵形式,调节器法兰式连接于PAV6.3之上、

螺纹拧入式连接于PAV10之上。连续工作压力均为350 bar。

2、Parker派克PV系列轴向柱塞泵有带标准压力调节器和带功率调节器两种选择。最大排量从16至270ml/rev,额定工作压力为

350bar,最低转速为每分钟300转,泄油口朝上。型号有:PV016, PV020, PV023, PV032, PV040, PV046, PV063, PV080, PV092,

PV140, PV180, PV270等。

3、Parker派克PV/PV系列双联轴向柱塞泵是由两个PV系列轴向柱塞泵组合而成,可以提供不同的排量组合。单个泵的最大排量从16

至270ml/rev,额定工作压力为350bar,最低转速为每分钟300转,泄油口朝上。

4、Parker派克PV/GP系列双联泵是由一个PV系列轴向柱塞泵和一个GP系列齿轮泵组合而成,可以提供不同的排量组合。PV系列柱塞

泵的最大排量从16至270ml/rev,额定工作压力为350bar,最低转速为每分钟300转,泄油口朝上。GP系列齿轮泵的排量从1.6至

7.9ml/rev,额定工作压力至210bar。

5、Parker派克PVM系列轴向柱塞泵有带标准压力调节器和带遥控压力调节器两种选择。最大排量从16至92ml/rev,额定工作压力为

250bar,最低转速为每分钟300转,泄油口朝上。型号有:PVM016, PVM020, PVM023, PVM028, PVM032, PVM040, PVM046, PVM063,

PVM080, PVM092等。

6、Parker派克PVP系列轴向柱塞泵最大排量从16至140ml/rev,额定工作压力为250bar,最低转速为每分钟500转。型号有:PVP016,

PVP023, PVP033, PVP041, PVP048, PVP060, PVP076, PVP100, PVP140等。

7、Parker派克PVS系列变量叶片泵为斜盘式结构,其优点有调节时间短,调节范围宽,噪音低,效率高。排量为8-50 ml/rev,出油

口额定压力为140bar,转速范围从1000-1800rpm,适应油液温度为-10至+70摄氏度。粘度范围为22-100mm2/s。型号有:PVS08,

PVS12,PVS16, PVS25, PVS32, PVS40, PVS50等。根据调节器功能不同,此系列变量叶片泵有PVS, PVY, PVD, PVH, PVM, PVK, PV

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)