极小极大搜索的算法过程:

参考文档:http://www.xqbase.com/computer/search_minimax.htm (经典)

  主要思想比较简单,但说清楚也不大容易。其核心思想是通过对于以后的状态进行预见式的暴搜,对可能的状态进行分析。理论上,如果能够搜索到最终状态,那么之后的走法都已经是确定的了。(这个地方觉得有些糊涂)

  对于局面形式的估计首先需要一个合理的估价函数。实际上是因为真正的搜索几乎都是无法搜索到所有的可能性,否则完全用0和1就能表示当前局面的胜负态了。所以需要对局面进行较为合理的分析估价。对于某一方来说都是要使得最终局面状态值(理论上,最终局面状态有且仅有一个)获得最大,所以对于两方来说,可以通过一方估价正越大表示胜率越大,另一方估价正越小(负越大)表示胜率越大。

  因此出现了极小极大搜索算法。

  从最简单的情况开始分析,首先确定我方要使得最终局面估价最大,而非当前局面估价最大,所以需要预测下一个我方局面的估价如何。而在此之前的一步掌握权在对方的手上,自然会选择对他有利的状态(一定是最终局面形式最大的状态走法),也就是走对于对方最终局面估价最大的状态。因此我方的落子是根据所有下一个状态对方会如何走来决定的。最终局面估价是双方共同决定的。

  (常常会被Min和Max状态搞乱,其实不要管这个,花时间弄明白其中的含义,写出来自然能够明白(其实Min()表示走到当前可预见的最后的状态的最小值,Max()反之))

伪代码如下:

int MinMax(int depth) {
 if (SideToMove() == WHITE) { // 白方是“最大”者
  return Max(depth);
 } else {           // 黑方是“最小”者
  return Min(depth);
 }
}
 
int Max(int depth) {
 int best = -INFINITY;
 if (depth <= 0) {
  return Evaluate();
 }
 GenerateLegalMoves();
 while (MovesLeft()) {
  MakeNextMove();
  val = Min(depth - 1);
  UnmakeMove();
  if (val > best) {
   best = val;
  }
 }
 return best;
}
 
int Min(int depth) {
 int best = INFINITY; // 注意这里不同于“最大”算法
 if (depth <= 0) {
  return Evaluate();
 }
 GenerateLegalMoves();
 while (MovesLeft()) {
  MakeNextMove();
  val = Max(depth - 1);
  UnmakeMove();
  if (val < best) {  // 注意这里不同于“最大”算法
   best = val;
  }
 }
 return best;
}

一个简便的实现方法,通过来回正负的变化来减少代码量,便于维护。

int NegaMax(int depth) {
 int best = -INFINITY;
 if (depth <= 0) {
  return Evaluate();
 }
 GenerateLegalMoves();
 while (MovesLeft()) {
  MakeNextMove();
  val = -NegaMax(depth - 1); // 注意这里有个负号。
  UnmakeMove();
  if (val > best) {
   best = val;
  }
 }
 return best;
}

剪枝方法也有很多,最经典的莫过于alpha-beta剪枝了。

参考文档:http://www.xqbase.com/computer/search_alphabeta.htm

  1)β剪枝:

  说的通俗一些,比如当前是我方下子,并且下一个我方局面的估价已经完成(递归),即博弈树的第三层已经预知。中间第二层即对方局面,可知对方走的必然是使得最终局面估价最小的一步,故我方当前要下子显然要使得在对方走估价最小的一步能达到的最大的估价。也就是第一层选取的走法是走向 第二层每一个局面对应的最小最终估价走法到达的 最大的局面。

  实现中,你实际上不是站在第一层的视角来看,而是在第二层搜索时进行的,故需要保留第一层已经搜索的最大值,而对于第二层的对手来说,我们是敌人。从上帝视角来看,alpha值为当前棋手预估的最终估价的最大值,beta值为上一个局面(实际上先前那个局面还没下,保留对于先前那个局面)对手棋手预估的最终估价的最小值。也就是如果当前走法能够走到比先前那个局面的棋手预估的最终估价的最小值要大(对手显然不会走这步,因为至少估价比当前小),就直接返回(因为对手不会让你走到这个状态,所以之后怎么走都不用管了)。

  2)  α剪枝:即相反的情况。

伪代码如下:

int AlphaBeta(int depth, int alpha, int beta) {
 if (depth == 0) {
  return Evaluate();
 }
 GenerateLegalMoves();
 while (MovesLeft()) {
  MakeNextMove();
  val = -AlphaBeta(depth - 1, -beta, -alpha);
  UnmakeMove();
  if (val >= beta) {
   return beta;
  }
  if (val > alpha) {
   alpha = val;
  }
 }
 return alpha;
}

极小极大搜索 的个人理解(alpha-beta剪枝)的更多相关文章

  1. Triangle War POJ - 1085 极小极大搜索

    参考链接:https://www.cnblogs.com/nwpuacmteams/articles/5697873.html 极小极大搜索 的个人理解(alpha-beta剪枝):https://w ...

  2. 极小极大搜索方法、负值最大算法和Alpha-Beta搜索方法

    1. 极小极大搜索方法    一般应用在博弈搜索中,比如:围棋,五子棋,象棋等.结果有三种可能:胜利.失败和平局.暴力搜索,如果想通过暴力搜索,把最终的结果得到的话,搜索树的深度太大了,机器不能满足, ...

  3. 转:极小极大搜索方法、负值最大算法和Alpha-Beta搜索方法

    转自:极小极大搜索方法.负值最大算法和Alpha-Beta搜索方法 1. 极小极大搜索方法    一般应用在博弈搜索中,比如:围棋,五子棋,象棋等.结果有三种可能:胜利.失败和平局.暴力搜索,如果想通 ...

  4. 软件发布版本区别介绍-Alpha,Beta,RC,Release

    Alpha: Alpha是内部测试版,一般不向外部发布,会有很多Bug.除非你也是测试人员,否则不建议使用. 是希腊字母的第一位,表示最初级的版本 alpha就是α,beta就是β alpha版就是比 ...

  5. 软工+C(4): Alpha/Beta换人

    // 上一篇:超链接 // 下一篇:工具和结构化 注:在一次软件工程讨论课程进度设计的过程中,出现了这个关于 Alpha/Beta换人机制的讨论,这个机制在不同学校有不同的实施,本篇积累各方观点,持续 ...

  6. 软工+C(2017第4期) Alpha/Beta换人

    // 上一篇:超链接 // 下一篇:工具和结构化 注:在一次软件工程讨论课程进度设计的过程中,出现了这个关于 Alpha/Beta换人机制的讨论,这个机制在不同学校有不同的实施,本篇积累各方观点,持续 ...

  7. K 班1-7,alpha,beta 作业成绩汇总

    K 班1-7,alpha,beta 作业成绩汇总 千帆竞发 详细得分 短学号 名 1 2 3 4 5 6 7 alpha beta TOTAL 505 基智 4.55 1 -2 0 0 -10 4.3 ...

  8. 软件版本GA,RC,alpha,beta含义

    软件版本GA,RC,alpha,beta含义 (1)RC:(Release Candidate) Candidate是候选人的意思,用在软件上就是候选版本.Release.Candidate.就是发行 ...

  9. 扩增子分析解读6进化树 Alpha Beta多样性

    分析前准备 # 进入工作目录 cd example_PE250 上一节回顾:我们的OTU获得了物种注释,并学习OTU表的各种操作————添加信息,格式转换,筛选信息.   接下来我们学习对OTU序列的 ...

随机推荐

  1. __new__方法以及TypeError: object() takes no parameters的处理

    一些python书或博客将类中的__init__方法称为构造函数,而实际上这种说法是不严格的,因为创建实例的方法是__new__,实例初始化的方法是__init__.__new__方法会返回一个实例, ...

  2. android 如何获取当前的Activity类名

    比如友盟统计页面停留时间,咱们需要知道当前页面停留了多久. 一般我们都有一个父类Activity,用下面的方法可以获得完整的包名.类名结构 this.getLocalClassName() 输出如下: ...

  3. Linux CentOS6环境下MySQL5.1升级至MySQL5.5版本过程

    转载地址:http://www.laozuo.org/6145.html 老左今天有在帮朋友的博客搬迁到另外一台VPS主机环境,其环境采用的是LLSMP架构的,原先的服务器采用的是LNMP网站环境,其 ...

  4. linux 第三周

    linux内核目录结构 arch目录包括了所有和体系结构相关的核心代码.它下面的每一个子目录都代表一种Linux支持的体系结构,例如i386就是Intel CPU及与之相兼容体系结构的子目录.PC机一 ...

  5. spring cron表达式及解析过程

    1.cron表达式 cron表达式是用来配置spring定时任务执行时间的字符串,由5个空格分隔成的6个域构成,格式如下: {秒}  {分}  {时}  {日}  {月}  {周} 每一个域的含义解释 ...

  6. Vue.js项目部署在Tomcat服务器上

    1.在本地的Vue框架中 执行npm run build  将我们的项目打包到dist 文件夹中 2.在服务器上的Tomcat的 webapps文件夹下,新建一个文件夹如:frontvue 3.启动t ...

  7. java和groovy的混用

    java在语言的动态性方便不是很灵活,如果你想快速增加或改变一些方法,那么只能通过反射机制,并且参数传递的格式很严格. 相比之下,基于groovy可以快速写出一些自定义方法,并能和java很好结合,类 ...

  8. C语言之浅析网络包解析

    1.这几天研究skynet中的 lua-netpack.c 中的解析数据包过程.于是把lua部分去掉,修改了一些接口,留下解包相关的代码.再结合云风写的网络代码的例子, 写了一个最简单形式的客户端封包 ...

  9. Restore IP Addresses,将字符串转换成ip地址

    问题描述: Given a string containing only digits, restore it by returning all possible valid IP address c ...

  10. MySQL索引失效的场景

    WHERE字句的查询条件里有不等于号(WHERE column!=-),MYSQL将无法使用索引 类似地,如果WHERE字句的查询条件里使用了函数(如:WHERE DAY(column)=-),MYS ...