大三的人工智能课学的alpha和beta剪枝,我记得当时明明学会了,现在研一又上人工智能课,课堂小测验,我居然把剪枝规则忘得一干二净。于是决定写下来,万一以后还用的上。
整个过程类似深度搜索,只有最底下的叶子结点有权值,如图所示。
条件: MAX层想从其子节点中获得最大值,而MIN层想从子节点获得最小值。alpha对应当前节点的可能取得min值,beta对应当前节点可能取得max值。
对于上图中的例子:
首先对于第一个节点,即值为6的叶子结点[1],此时可确定父节点e(在MAX层)的alpha=6,即范围为(6,正无穷),
(因为父节点e要从叶子节点[1]叶子节点[2]中获取最大值。)
再观察[2],[2]<[1]无需更新,即e的范围为(6,正无穷),
因此可确定e的父节点b(MIN层)的范围为(负无穷,6)(因为节点b要从其子节点e、f、g中获取最小值)
再沿着b的另一个分支走到节点[3],更新其父节点f(在MAX层)的范围为(7,正无穷),好了这是关键点,f的父节点b为(负无穷,6),也就是说b想获取尽可能小的值的情况下,最差的情况也可以得到6,而f节点想获取尽可能大的值的情况下,最差的情况会得到7,那么f节点对b节点的愿望无能为力(b节点目前的最小值为6,想获得比6还小的值),一句话概括 即f的范围与其父节点b的范围无交集,所以f节点不用努力了,直接把它的其他子节点[4]和[5]剪掉,按照定义(图中的两段话),这是beta剪枝。
同理可得:节点g的范围(8,正无穷)与其父节点b(负无穷,6)无交集,即愿望有冲突,所以节点g的后续不用再看,直接剪掉[7]。
当b节点下的所有子节点都遍历完成后,即b节点的值完全确定了,那么可以确定其父节点a(在MAX层)的范围了,即(6,正无穷)。
后续做法完全一致,按照前面的做法得到c节点的范围(负无穷,3),与其父节点a(6,正无穷)有冲突,所以后面的i、j不用看,直接剪掉。
总结: 搜索从上到下,从左到右的顺序,深度搜索,每次确定一个节点x的值后,就立刻往上确定其父节点y的范围:
一:(y第一次被遍历到,之前不存在值),
(1)如果父节点y的范围和y的父节点z的范围有冲突,那就不用再遍历z的其他子节点了(即y的兄弟节点),直接剪掉;
(2)如果z节点无范围,立刻更新z的范围。
二:y的范围已存在的情况下,就比较y的两个范围,保留最优的,再继续看y的其他子节点。
对MIN层的节点进行剪枝,即alpha剪枝。
对MAX层的节点进行剪枝,即beta剪枝。
总结的总结: 每次在确定某节点的范围后,往上康康是否符合它的父节点的范围,不符合就说明这个某节点已经废了,它的孩子通通剪掉,无需再考虑。
还有某个节点的值已经确定了才能确定它父节点的范围,而不能根据范围确定范围。
上图中每个节点都写的范围,容易混淆。
总结完毕。