Alpha-Beta 剪枝

极大极小算法是一种空间搜索零和博弈算法!使得对手利益最小化我方利益最大化!

在局面确定的双人对弈里,常进行对抗搜索,构建一棵每个节点都为一个确定状态的搜索树。奇数层为己方先手,偶数层为对方先手。搜索树上每个叶子节点都会被赋予一个估值,估值越大代表我方赢面越大。我方追求更大的赢面,而对方会设法降低我方的赢面,体现在搜索树上就是,奇数层节点(我方节点)总是会选择赢面最大的子节点状态,而偶数层(对方节点)总是会选择我方赢面

过程

Minimax 算法的整个过程,会从上到下遍历搜索树,回溯时利用子树信息更新答案,最后得到根节点的值,意义就是我方在双方都采取最优策略下能获得的最大分数。

例题

约定inf为无穷,以这棵树为例,题目服用了南京财经大学蒋玖川老师的课堂习题为例,请老师见谅。

Alpha-Beta 剪枝_第1张图片

 第一步我们进行初始化a=-inf beta=+inf 在这里我们从左到右开始遍历树,首先初始化从根节点,传递根节点的值到左边的可选择的节点

Alpha-Beta 剪枝_第2张图片

 开始搜索!

 可知最左边的叶子节点为5,由于max节点现在具有可决策选择,故更新该节点的val为5,且a更新为5,beta不更新,由于分数为5的节点的aAlpha-Beta 剪枝_第3张图片

 在完成最左边max层的值确认后,更新D的取值范围,由于D是min,故D的beta更新为5,a不更新

Alpha-Beta 剪枝_第4张图片

 D将开始搜索他的右子树,此时传递D的a与beta的值给E

Alpha-Beta 剪枝_第5张图片

 E开始搜索他的左子树,发现E的左子节点的值为10,E更新a为10,由于E节点的a>beta,故进行beta剪支减去剩余的子节点,

Alpha-Beta 剪枝_第6张图片

 此时根节点的左子树搜索完成,更新根节点的a与beta的值,由于根节点是最大选择,故根节点的a更新为5,beta不更新。

开始遍历根结点中间的子树,同样传递根节点的a与beta给中间的子树

Alpha-Beta 剪枝_第7张图片

 开始搜索中间的子树,从中间子树的最左边字数开始搜索,发现1、2、2当中最大的为2,更新他的父节点的a值为2,此时F节点的值需要进行更新,由于F是最小选择层,故设置beta为2,由于a>beta,故进行剪掉F节点的右子树

Alpha-Beta 剪枝_第8张图片

 更新F的分数为2,由于F值为2,根节点一句贪心算法局部最优点不会选择她,所以不需要更新根结点的a值。下面开始搜索根节点的右子树的,同样刚开始也是传递根节点的a和beta值给右子树的具有选择权力的左边的节点

Alpha-Beta 剪枝_第9张图片

 搜索G节点的子结点,发现G的子节点为12,更新G的a=12以及G的分数等于12,同时更新G节点的父节点B的beta的值为12,此时G节点的a

Alpha-Beta 剪枝_第10张图片

 继续搜索B的中间的子树,同样传递B的a与beta值给到B的中间的子节点M

Alpha-Beta 剪枝_第11张图片

 M开始搜索,由于M是最大选择,M的最大子节点为4,更新M的a与分数为4,此时M的a不大于M的beta的值,所以不进行剪支

同时更新B节点的选择范围,B由于是最小选择,他的beta目前可更新为M点的分数为4,此时B点的a为5,beta为4,a>beta,所以对B为未搜索的子树进行剪纸,不再搜索

最后所有子树搜索完毕,更根节点进行最大化利益选择为5

Alpha-Beta 剪枝_第12张图片

 

算法实现:

int alpha_beta(int u, int alph, int beta, bool is_max)

{

                if (!son_num[u]) return val[u];

                if (is_max) {

                        for (int i = 0; i < son_num[u]; ++i) {

                         int d = son[u][i];

                         alph = max(alph, alpha_beta(d, alph, beta, is_max ^ 1));

                         if (alph >= beta) break;

}

                         return alph;

                         } else {

                             for (int i = 0; i < son_num[u]; ++i) {

                                   int d = son[u][i];

                                   beta = min(beta, alpha_beta(d, alph, beta, is_max ^ 1));

                                     if (alph >= beta) break;

                                  }

                            return beta; }

}

你可能感兴趣的:(剪枝,算法,机器学习)