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