zoukankan      html  css  js  c++  java
  • 【算法】博弈树的α-β剪枝

    在MiniMax函数中我们已经知道,对于MIN节点,我们是要找其子节点的最小估值,如上面的代码,当min’s turn时候,我们先估值,如果 score < beta then beta = score,即是把MIN节点的孩子中的估值最小值给赋给Beta,这时候在判断Alpha是否大于等于Beta,Alpha是这个MIN节点的父亲节点的下界,即MAX节点,想一想,MAX应该是要找其子节点的最大估值,而它目前的下界Alpha都大于Beta了,那么可以遇见在将来这个MIN节点肯定不会被它的父亲MAX节点选取了,那么此时这个MIN节点可以停止继续展开孩子估值了,因为注定不会被选取,继续进行只是在浪费时间和资源。上面讲的这个过程就好像两个人,其中一个人有几个口袋(即是几个MIN节点),每个口袋有几种东西,你(MAX)可以选取其中一个口袋,而无疑他会把你选取口袋里价值最低的物品给你(即MIN取最小值),而你为了获得最大收益只能判断这几个口袋所有的“最低价值物品”中那件还算是最有价值(即是MAX取最大值),MiniMax算法是你把对方所有口袋翻个遍再判断要哪个口袋,无疑这样效率不高。那么Alpha-Beta算法所做的就是:首先你先把第一个口袋里所以物品依次翻出来,假如第一个口袋里是车钥匙和手表,那么假如选这个口袋你只能得到手表,这个就是Beta了,因为此时还没有Alpha值,那么你把这个第一次获得的Beta再向上赋给Alpha,再翻第二个口袋,假如第一次翻出的是咸鱼(ew~~~),先赋给Beta,那么这个咸鱼Beta怎么说都比第一个口袋的表垃圾吧?!即此时手表Alpha >= 咸鱼Beta,因为对方只会把口袋价值最低的物品给你,这个口袋要么最低是咸鱼,要么还有比咸鱼给无语的东西,意味着这个口袋已经不值得在往下翻了,就算里面还有很多东西。

    如果你把上面伪代码中的加粗部分去掉,那便是miniMax的算法,所以说这个算法其实是一个通过减少不必要的分支来节约时间资源的“砍枝”算法。

     int AlphaBeta(int depth, int alpha, int beta) {
                  int hashf = hashfALPHA;    //开始时的结点类型应该是All-Nodes,有些地方称为ALPHA类型结点
                  //这里要探查置换表
                  if (depth == 0) {   // 叶子结点,评估,写入置换表,返回即可
                     val = Evaluate();
                     RecordHash(depth, val, hashfEXACT); // 叶子结点肯定是PV-Nodes
                     return val;
                  }
                  GenerateLegalMoves();
                  while (MovesLeft()) {
                     MakeNextMove();
                           //注意Negamax风格的调用方式,前面有个负号,后面的参数是-beta和-alpha
    
                   // Negamax的含义中Nega就是指这里的负号
                     val = -AlphaBeta(depth - 1, -beta, -alpha);  
                     UnmakeMove();
                     if (val >= beta) {   // 剪枝情况判断
                        RecordHash(depth, beta, hashfBETA);  //这时的结点类型是Cut-Nodes
                        return beta;
                     }
                     if (val > alpha) {   // Negamax中的max就是指的这一段,要记录最大的评估值,这里没有引入一个新变量,直接就用了alpha变量
                        hashf = hashfEXACT;   // 只要alpha值一发生变化,这个结点类型就是PV-Nodes了!
                        alpha = val;
                     }
                   }
                   RecordHash(depth, alpha, hashf);
                   return alpha;   // 此时的alpha就是记录了当前结点的所有子结点的最大的负评估值!
               }
  • 相关阅读:
    bzoj 3059: 归途与征程
    bzoj 4827: [Hnoi2017]礼物
    bzoj 4826: [Hnoi2017]影魔
    bzo j4825 [Hnoi2017]单旋
    hackerrank Week of Code 31
    bzoj 3615: MSS
    bzoj2505: tickets
    bzoj4813: [Cqoi2017]小Q的棋盘
    bzoj4821: [Sdoi2017]相关分析
    RedisTemplate访问Redis数据结构(一)——String
  • 原文地址:https://www.cnblogs.com/KID-XiaoYuan/p/6422194.html
Copyright © 2011-2022 走看看