最清晰易懂的MinMax算法和Alpha-Beta剪枝详解

参考文章

http://web.cs.ucla.edu/~rosen/161/notes/alphabeta.html
https://www.cnblogs.com/pangxiaodong/archive/2011/05/26/2058864.html

一、MinMax算法

  Minimax算法(亦称 MinMax or MM)又名极小化极大算法,是一种找出失败的最大可能性中的最小值的算法。

  Minimax算法常用于棋类等由两方较量的游戏和程序。该算法是一个零总和算法,即一方要在可选的选项中选择将其优势最大化的选择,另一方则选择令对手优势最小化的方法。而开始的时候总和为0。很多棋类游戏可以采取此算法,例如井字棋(tic-tac-toe)。


  以上是来自WIKI百科的解释,其实说的通俗一点,就是有两个人下棋,先手希望下一步的局面是自己胜算最大的局面,而后手则希望下一步的局面是先手胜算最小的局面(因为先手输,后手就会赢)。

  那么,如何来判断当前的局面的胜算到底怎么样呢?我们可以设置一个估价函数,按照某种方案来计算当前局面的优劣程度。

  (建议先跳过以下内容)

  然后在这种想法的前提下,就是高能的博弈过程。如果只向后看一步(也就是直接计算下一步的估价值)的话,那情况就是:先手预测了自己走完这一步的所有可能的局面,然后选择了所有走法中局面看起来最好的(估价函数的结果最好的)走法。之后,后手也预测了自己走完这一步的所有可能的局面,然后也选择了所有走法中局面看起来最好的(估价函数的结果最好的)走法。如此循环往复,直到最后游戏结束。(GG,即Good Game)

  如果这两个棋手比较优秀,可以往后看两步(也就是只直接计算往后数两步的估价值),那么,情况就是这样的:先手预测了自己走完这一步的所有可能局面,并同时预测了对手的所有应对方案(也就是对手会选择让下一步局面估价函数最小的走法,所以先手这一步应该选择,让后手不管走么走估价函数都尽量大的走法),综合这些信息,选择了一个最优的局面,后手也是如此。也就是我猜到了我这么走,你会怎么走,所以我选择这么走的高端玩法。

  当然,也可以往后看三步(也就是只直接计算往后数三步的估价值),那么,情况就是这样的:先手预测了自己走完这一步的所有可能局面,并同时预测了对手的所有应对方案,还同时又想到了自己在面对对手的每种应对方案时的所有可能走法,从中选择一个最优秀的,后手也是如此。也就是,我猜到了我这么走,你会那么走,然后我会这么走,所以我选择这么走的更高端玩法。


  (跳到这儿就可以了)

  不知道大家是不是懵逼了,其实看不懂也没关系,上面的大家可以当成废话(那你写这么多干嘛?MDZZ),下面我们就要上图啦,结合图示,一下子就可以明白怎么回事了。

  我们用正方形来代表先手(选择估价最大的局面),圆形来代表后手(选择估价最小的局面)只有叶子节点才可以直接计算估价值

  则我们假设棋局的博弈树如下(往后看4步),那么先手应该如何选择呢:

  首先,先手应该计算后手在第四步的时候应该会选择价值为多大的局面(即从所有子节点中选择最小的),如下图(红色字体):

  然后先手在计算自己在第三步时应该如何选择(即从所有子节点中选择最大的),如下图(红色字体):

  然后先手在计算后手在第三步时应该如何选择(即从所有子节点中选择最小的),如下图(红色字体):

  最后先手就可以决定下一步应该怎么走了(即从所有子节点中选择最大的),如下图(红色字体):

  所以,如果先后手都进行最有决策的话,棋局的走向则下图所示(红线):

  (当然,如果后手不是进行最优决策的话,棋局的走向就不一定是这样的了,先手也可以尝试走有风险,但是收益更高的局面,这就不在我们的讨论范围之内了)

  可以看到,如果按照MinMax算法来进行决策的话,需要的计算量是随着向后看的步数的增加而呈指数级增长的。但是,这些状态中其实是包含很多不必要的状态的,所以我们可以进行剪枝。

注:真实的搜索顺序并不一定是一层一层的进行的

二、Alpha-Beta剪枝

   Alpha-beta(α−β\alpha - \betaα−β)剪枝的名称来自计算过程中传递的两个边界,这些边界基于已经看到的搜索树部分来限制可能的解决方案集。 其中,Alpha(α\alphaα)表示目前所有可能解中的最大下界,Beta(β\betaβ)表示目前所有可能解中的最小上界。

  因此,如果搜索树上的一个节点被考虑作为最优解的路上的节点(或者说是这个节点被认为是有必要进行搜索的节点),那么它一定满足以下条件(NNN是当前节点的估价值):
α≤N≤β\alpha \leq N \leq \beta α≤N≤β
  在我们进行求解的过程中,α\alphaα和β\betaβ会逐渐逼近。如果对于某一个节点,出现了α>β\alpha > \betaα>β的情况,那么,说明这个点一定不会产生最优解了,所以,我们就不再对其进行扩展(也就是不再生成子节点),这样就完成了对博弈树的剪枝。

  可能这个过程描述起来还是有一些抽象,那么,我们就用图像(依旧是往后看4步)来还原模拟一下这个过程:

  首先,我们开始从根节点向下进行搜索,直到进行了四步为止(废话,不到4步没有值呀),红色的序号代表顺序。

  当我们搜索到了第一个叶子节点的时候,我们发现它的权值是3,并且它的父节点是Min节点,又因为父节点的最小上界β>3\beta > 3β>3,所以我们更新父节点,令β=3\beta = 3β=3。(因为父节点要取最小值,这个最小值不会比3更大,所以我们更新其上界)然后继续向下搜索。

  因为17比3大,所以这个节点我们可以无视掉(没啥用啊)。我们已经搜索完了当前这个Min节点的所有孩子,所以我们返回它的节点值给它的父节点(Max节点),尝试更新父节点的α\alphaα值。(因为这是一个Max节点,他的孩子的估价值和α、β\alpha、\betaα、β值已经确定了,所以父节点取值范围的下界也需要被更新),此处更新父节点,令α=3\alpha = 3α=3。然后继续进行搜索,注意新生成的子节点的 α、β\alpha、\betaα、β 值继承自父节点

  继续搜索,至叶子节点:

  我们发现它的权值是2,并且它的父节点是Min节点,又因为父节点的最小上界β>2\beta > 2β>2,所以我们更新父节点,令β=2\beta = 2β=2。(因为父节点要取最小值,这个最小值不会比2更大,所以我们更新其上界)。然后此时我们发现父节点出现了α>β\alpha > \betaα>β的情况,说明最优解不可能从这个节点的子节点中产生,所以我们不再继续搜索它的其他子节点。(这就是β\betaβ剪枝)并继续返回其节点值,尝试更新父节点。因为父节点的α=3>2\alpha = 3 > 2α=3>2,所以更新失败。

  然后我们已经搜索完了当前这个Max节点的所有子节点,所以我们返回它的节点值,并尝试更新他的父节点的β\betaβ 值。因为父节点的β>3\beta > 3β>3,所以我们令$\beta = 3 $。并继续向下搜索至叶子节点,注意新生成的子节点的 α、β\alpha、\betaα、β 值继承自父节点

  然后,我们发现15并不能更新当前节点的β\betaβ值,所以令当前节点权值为15,并返回其权值,尝试更新其父节点(Max节点)的α\alphaα值。因为其父节点的α<15\alpha < 15α<15,所以我们令$\alpha = 15 $。

  此时,该节点α=15,β=3\alpha = 15 , \beta = 3α=15,β=3,α>β\alpha > \betaα>β,则说明其子节点并不包含最优解,不需要在进行搜索。所以返回其节点权值给父节点(Min节点),尝试对父节点的β\betaβ值进行更新。父节点的β<15\beta < 15β<15,则不需要进行更新。同时可确定父节点的权值为3。

  继续返回权值给父节点,尝试更新父节点的α\alphaα,发现父节点α<3\alpha < 3α<3,则令α=3\alpha = 3α=3,并继续向下搜索直至叶子节点。注意新生成的子节点的 α、β\alpha、\betaα、β 值继承自父节点

  从叶子节点返回权值给父节点(Min节点),并尝试更新其父节点的β\betaβ值,因为父节点β>2\beta > 2β>2,所以,令β=2\beta = 2β=2,此时有α>β\alpha > \betaα>β,说明其子节点并不包含最优解,不需要再进行搜索。所以返回其节点权值给父节点(Max节点),尝试对父节点的α\alphaα值进行更新。因为父节点α>2\alpha > 2α>2,无需进行更新,继续搜索其子节点至叶子节点。

  从叶子节点返回权值给父节点(Min节点),并尝试更新其父节点的β\betaβ值,因为父节点β>3\beta > 3β>3,所以,令β=3\beta = 3β=3,同时确认父节点权值为3。

  继续返回权值给父节点,并尝试更新其父节点的α\alphaα值,因为父节点α=3\alpha = 3α=3,所以无需进行更新,同时确定该节点权值为3。

  因为该节点的所有子节点全部搜索完毕,所以返回该点权值给父节点,并尝试更新其父节点的β\betaβ值,因为父节点β>3\beta > 3β>3,所以,令β=3\beta = 3β=3,同时确认父节点权值为3。因为此时有α=β=3\alpha = \beta = 3α=β=3,所以无需再搜索其子节点,直接返回权值给根节点,并尝试更新根节点的α\alphaα值,因为根节点α=3\alpha = 3α=3,所以无需进行更新。

  根节点的所有子节点搜索完毕,则得出最优解为3。

  可以对比一下不加剪枝与加了剪枝之后的搜索过程,可以发现Alpha-Beta剪枝对算法的性能有了很大的提升。

三、代码

伪代码如下:

MinMax算法:

function minimax(node, depth) // 指定当前节点和搜索深度// 如果能得到确定的结果或者深度为零,使用评估函数返回局面得分if node is a terminal node or depth = 0return the heuristic value of node// 如果轮到对手走棋,是极小节点,选择一个得分最小的走法if the adversary is to play at nodelet α := +∞foreach child of nodeα := min(α, minimax(child, depth-1))// 如果轮到我们走棋,是极大节点,选择一个得分最大的走法else {we are to play at node}let α := -∞foreach child of nodeα := max(α, minimax(child, depth-1))return α;

Alpha-Beta剪枝:

function alphabeta(node, depth, α, β, Player)         if  depth = 0 or node is a terminal nodereturn the heuristic value of nodeif  Player = MaxPlayer // 极大节点for each child of node // 极小节点α := max(α, alphabeta(child, depth-1, α, β, not(Player) ))   if β ≤ α // 该极大节点的值>=α>=β,该极大节点后面的搜索到的值肯定会大于β,因此不会被其上层的极小节点所选用了。对于根节点,β为正无穷break                             (* Beta cut-off *)return αelse // 极小节点for each child of node // 极大节点β := min(β, alphabeta(child, depth-1, α, β, not(Player) )) // 极小节点if β ≤ α // 该极大节点的值<=β<=α,该极小节点后面的搜索到的值肯定会小于α,因此不会被其上层的极大节点所选用了。对于根节点,α为负无穷break                             (* Alpha cut-off *)return β
(* Initial call *)
alphabeta(origin, depth, -infinity, +infinity, MaxPlayer)

最清晰易懂的MinMax算法和Alpha-Beta剪枝详解相关推荐

  1. alpha,beta剪枝详解

    α,β剪枝详解\alpha,\beta剪枝详解α,β剪枝详解 示例图 步骤详解 基础原理 这里我们先要理解什么是α,β\alpha,\betaα,β剪枝:α\alphaα是下界,β\betaβ是上界. ...

  2. 数据结构与算法—最小生成树(Prim算法和Kruskal算法算法详解)

    前言 在数据结构与算法的图论中,(生成)最小生成树算法是一种常用并且和生活贴切比较近的一种算法.但是可能很多人对概念不是很清楚.我们看下百度百科对于最小生成树定义: 一个有 n 个结点的连通图的生成树 ...

  3. 五子棋AI算法第三篇-Alpha Beta剪枝

    剪枝是必须的 五子棋AI教程第二版发布啦,地址:https://github.com/lihongxun945/myblog/labels/%E4%BA%94%E5%AD%90%E6%A3%8BAI% ...

  4. alpha-beta剪枝五子棋c语言,五子棋AI算法第三篇-Alpha Beta剪枝

    剪枝是必须的 上一篇讲了极大极小值搜索,其实单纯的极大极小值搜索算法并没有实际意义. 可以做一个简单的计算,平均一步考虑 50 种可能性的话,思考到第四层,那么搜索的节点数就是 50^4 = 6250 ...

  5. php计算股票均线,均线怎么算?均线的计算方法详解

    均线怎么算?均线的计算方法详解 学习股票知识首先需要了解各大技术指标,股票均线是最常用的技术指标,新股民学习股票均线肯定有很多不了解的地方,今天股票知识就给大家讲解一下股票均线是怎么来的? 日均线的计 ...

  6. 一周刷爆LeetCode,算法da神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解 笔记

    一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解 笔记 教程与代码地址 P1 出圈了!讲课之外我们来聊聊 ...

  7. 基于python的AI五子棋实现(极大极小值搜索和alpha beta剪枝)

    1.极大极小值搜索介绍 人机博弈是人工智能的重要分支,人们在这一领域探索的过程中产生了大量的研究成果,而极小化极大算法(minimax)是其中最基础的算法,它由Shannon在1950年正式提出. M ...

  8. 五子棋AI算法-Alpha Beta剪枝

    上一篇讲了极大极小值搜索,其实单纯的极大极小值搜索算法并没有实际意义. 可以做一个简单的计算,平均一步考虑 50 种可能性的话,思考到第四层,那么搜索的节点数就是 50^4 = 6250000,在我的 ...

  9. 巅峰战舰今日服务器全部维护,巅峰战舰12月7日更新维护公告 12.7新增玩法和舰船属性调整详解[图]...

    类型:策略卡牌 大小:827.38MB 评分:10 平台: 巅峰战舰今天进行了临时维护更新,具体更新了什么内容?估计小伙伴们不太清楚,没关系,下面是小麦整理出来的12.7新增玩法和舰船属性调整详解,希 ...

最新文章

  1. php log在哪里看,PHP Log时时查看小工具
  2. 面试--js实现继承的几种方式
  3. 【快乐水题】686. 重复叠加字符串匹配
  4. unity片元着色器中获取屏幕坐标_Unity踩坑笔记(持续更新)
  5. redis内存行数据库细节
  6. IE与Chrome对相对URL解析的区别
  7. 实例解析linux内核I2C体系结构(1)
  8. ajax传递数组,后台接收为null解决方法
  9. java 504错误怎么解决_求助java.lang.NoClassDefFoundError怎么解决,报错信息如下
  10. linux系统在硬盘上安装程序,怎么样用硬盘上的镜象文件来安装Linux系统?我都进入安装界面了,但是那个安装程序好像找不到那几个镜象文件,请指点...
  11. 真正中文攻略之ef - the first tale(含下载和汉化)
  12. 一文带你详细了解机房搬迁工作步骤及方案,强烈建议收藏备用!
  13. 基于FPGA的CYUSB3014双向通信实验
  14. ClasspathResource路径问题解决
  15. 仿今日头条后台管理系统(一)
  16. Java面试-001
  17. 用html5做课件,涨姿势┃一分钟PPT轻松转化H5,让“课件”动起来
  18. 有关七巧板复原的算法初步探讨
  19. APA系统中超声波雷达的安装调试使用说明
  20. java计算机毕业设计会员商城管理系统源码+mysql数据库+系统+lw文档+部署

热门文章

  1. 开源mysql执行平台_MySQL自动化审核平台部署说明
  2. Jboot初遇activiti
  3. c语言编程难学么,C语言编程学习难吗?
  4. 51单片机_7-1独立按键控制流水灯方向
  5. cs231n-assignment3的笔记
  6. Spring 注解@Value详解
  7. 靠2块钱月入4万:越朴素的方法,往往越挣钱
  8. 英语语法笔记——特殊句型(六)
  9. QTreeWidget实现搜索子节点功能
  10. html5性格测试,9种性格测试