人工智能 α-β剪枝
α-β剪枝相当于是对极大极小法的优化,通过剪枝减少某些结点的访问,它的搜索结果与极小极大法一致。
α:极大结点的估值下界;随着子结点的生成,α只可能上升。
β:极小结点的估值上界;随着子结点的生成,β只可能下降。
α剪支:当某极小结点的β值 ≤ 其先辈的极大结点的α值,则终止该极小结点之下的搜索,并令其估值为β,这种剪支称α剪支。(被剪枝子的子结点若是Max结点,则称此次剪枝为α剪枝)
β剪支:当某极大结点的值α ≥ 其先辈的极小结点的β值,则终止该极大结点之下的搜索,令其估值为α,这种剪支称β剪支。
例题:
输入说明:
第一行是一个数字n,后面跟着n行,每行3个数字,用空格分开每行的3个数字分别代表树的结点的id,估值,和父结点id。根结点的父结点id为-1。
输出说明:
第一行是搜索得到的走步及其估值,用三个空格分隔的数字表示。如1 3 1;表示从结点1到3的走步,其估值为1。 后面若干行,代表剪掉的枝子。每行前面两个数字分别代表被剪掉的枝子的父结点和子结点,如果是α剪枝,则两个数字后面是字符串alpha(被剪枝子的子结点若是Max结点,则称此次剪枝为α剪枝),否则是beta。数字和字符串之间都用空格分隔。
输入样例:(篇幅原因,换行省略了)
39
1 0 -1 2 0 1 3 0 1 4 0 2 5 0 2 6 0 3 7 0 3 8 0 4 9 0 4 10 0 5 11 0 5 12 0 5 13 0 5 14 0 6 15 0 6 16 0 7 17 0 7 18 0 8 19 5 8 20 -3 9 21 3 9 22 3 10 23 3 11 24 0 11 25 2 11 26 2 12 27 -3 12 28 0 12 29 -2 13 30 3 13 31 5 14 32 4 14 33 1 14 34 -3 15 35 0 15 36 6 16 37 8 16 38 9 17 39 -3 17
输出样例:
1 3 1
9 21 alpha
5 11 beta
5 12 beta
5 13 beta
15 35 alpha
7 17 beta
一开始不是很懂什么时候更新哪一层的 α α α 和 β β β,实际上它是在回溯回去的时候得到估值然后进行更新,且max层只更新 α α α,min层只更新 β β β,max层返回的是 α α α,min层返回的是 β β β(因为只有β被改变了,且这一层其实就是要确定的是这个值,这一层的α只是用来辅助判断剪枝的,因此不是返回α)。首先初值 α = − ∞ , β = + ∞ α=-∞,β=+∞ α=−∞,β=+∞,每次深搜的时候都将这一层的α和β传递给下面一层,在访问邻接点的时候之前就可以根据两者大小决定是否还需要访问其他的邻接点(即是否剪枝)。
剪枝的条件都是当前结点的 α ≥ β α≥β α≥β,就不用递归访问它的邻接点了,概念上被剪枝子的子结点若是Max结点,则称此次剪枝为α剪枝。
搜索过程是:进行dfs后,首先到达最左下面的叶子结点18,到达递归终止条件(18没有邻接点了),返回估值0到第四层min层,0比β的初值∞小,更新β为0(蓝色),此时 α = − ∞ α=-∞ α=−∞,不剪枝而接着访问8号结点的另一个邻接点19,返回值5,5比0大不更新,8号结点的所有邻接点访问结束,β估值确定为0(红色),因为8是min层结点,所以向上传递β到第三层4号结点,max层更新α,0比α初值-∞大,更新α为0(蓝色),此层的β是∞(黑色),不剪枝,接着递归访问4号结点的邻接点9,同时也把α=0,β等于∞传递给了第四层的结点9,此时也不满足剪枝条件,访问9的邻接点20,20是叶子返回了估值-3,结点9处β取 m i n ( − 3 , ∞ ) min(-3,∞) min(−3,∞)的-3,此时如果不剪枝的话将会访问结点21,但是此处已经有 α = 0 ≥ β = − 3 α=0≥β=-3 α=0≥