• 象棋中常用的最小值最大值算法及剪枝算法


    1.象棋中通常需要推算当前局面下,每走一步之后的局面分,通常我们可以设定考虑几步棋,通常我们所说的算棋,而计算机的AI算法中最常用的就是最大值最小值算法,而剪枝算法是对最大值最小值算法的一种优化。

     

    如上图所示:

    1.如果在当前局面下,假设有三步可走的棋,走完之后得到的局面分分别为100,80,90,如果仅考虑一步的情况下,当然是选100所对应的棋走,这是最简单也是最短视的走法,这样的AI会让人认为太笨了。此时level=1

    2.如果考虑两步棋的情况,走完第一步之后,轮到对方走了,对方走完之后,此时的局面分是第三层的分,可能的走法有:走100分支的话,有三种可能:60,10,40,走80分支的话,有:50,30,20,走90分支的话,有:40,50,30,假设我们都不傻,都会挑使对方最不利的棋走,因此走100分支的话,对方可定会走10分支,如果走80分支的话,对方肯定走20分支,如果走90分支的话,对方肯定走30分支,因此我们为了使走两步之后(仅考虑2步,level=2),自己获得的局面分最大,使自己最有利,则必须走90分支,这样的话,对方无论怎么走,得到的最小值局面分都是30,都比走其他分支(100和80)的最小值要大。这就是最小值最大值算法。

    3.如果考虑三步棋的情况,此时level=3,到第四层局面的时候,此时level=0,即只需要直接计算当前每个分支的局面分即可,得到:15,35,8,9,25,15,34,25,8,20,18,10,7,14,32,21,16,15,

    此时我们如何走才最有利呢?

    a.假设第一步走100分支,则对方肯定走10分支,此时我们只能走9分支(getMaxScore),

    b.如果第一步走80分支,则对方肯定走20分支,此时我们只能走18分支(getMaxScore,获取最佳局面分)

    c.如果第一步走90分支,则对方肯定走30分支,此时我们只能走16分支(getMaxScore,获取最佳局面分)

    因此,我们只需要考虑在第四层中选取一个最大值即可。毫无疑问第一步肯定走80分支,然后对方走20分支,然后我们走18分支,此时的局面对我们最有利。

    因此总结如下:

    我们最终的目的是使最后得到的局面分最大为依据的。

    最小值,最大值算法交替使用,根据不同的考虑步数(level)有不同的走法。

    getMinScore()会调用getMaxScore(),getMaxScore()内部也会调用getMinScore()两个函数构成间接递归。

    4.剪枝算法:

    假设考虑这么一种情况:

    假设第二分支80下面的50换成5,且只考虑level=2的情况,此时我们第一步是求最小值(第三层的),第二步求最大值(第二层的),注意这是回朔算法,根据可能得到的结果(最终局面分)往回推,可能要走的棋步。

    当我们推演完第一分支(100)之后发现最小值为10,而当我们推演第二分支的时候,在求最小值时(第三层),遇到了5,显然5<10,并且此时的上一层(第二层,即100,80,90)要求的是最大值,因此该分支的其他分支(30,20)就不需要推演了,因为该分支的最小值(5)已经比上一分支(100-->60,10,40)中的最小值10要小,再推演下去已经没有意义了,因此可以把剩下的该分支的其他分支,舍弃掉,不需要计算了,大大降低了计算量,直接推演第三分之(90),俗称剪枝算法。

    因此我们需要传入一个参数,标记上一分支中的最值。如果该分支中的某一个值比上一分支中的最值还要小,该分支的其他分支,就可以忽略了,因为该分支肯定不在考虑范围之内了。因此可以提前结束本分支的计算,而直接计算下一分支。

  • 相关阅读:
    替换掉一段 以 $ 开头 $ 结尾 的字符串
    react 中使用 codemirror2(在线代码编辑器)读取 yaml 文件
    第四篇:前端读取文件 | FileReader 对象及其属性
    umi 如何使用 Mock 模拟数据
    loading 动画 系列
    网站页面上标签页小图标的添加方式
    Linux tail命令
    Python实现字符串反转的方法
    Redis 配置远程访问
    消息队列
  • 原文地址:https://www.cnblogs.com/ttss/p/4168909.html
Copyright © 2020-2023  润新知