极大极小值算法( Minimax algorithm)

在上文的博弈树中,如果我们令甲胜的局面值为1,乙胜的局面值为-1,而和局的值为0。当轮到甲走时,甲定会选择子节点值最大的走法:而轮到乙时,乙则会选择子节点值最小的走法。所以,对于中间节点的值可以有如下计算方法:如果该节点所对应的局面轮到甲走棋,则该节点的值是其所有子节点中值最大的一个的值。而如果该节点所对应的局面轮到乙走棋,则该节点的值是其所有子节点中值最小的一个的值。

对博弈树的这个变化仅仅是形式上的,本质上丝毫未变,但是这个形式更容易推广以运用到一般实际的情形。
既然建立整棵的搜索树不可能,那么,为当前所面临的局面找出一步好棋如何?也就是通过少量的搜索,为当前局面选择一步较好的走法。

在通常的棋局当中,一个局面的评估往往并不像输、赢、平3种状态这么简单,在分不出输赢的局面中棋局也有优劣之分。也就是说,要用更细致的方法来刻画局面的优劣,而不是仅仅使用1、-1、0三个数字刻画3种终了局面。假定我们有一个函数可以为每一局面的优劣评分。例如甲胜为+∞:乙胜为-∞:和局为0:其他的情形依据双方剩余棋子的数量及位置评定-∞~+∞之间的具体分数。这样我们可以建立一棵固定深度的搜索树,其叶子节点不必是终了状态,而只是固定深度的最深一层的节点,其值由上述函数评出:对于中间节点,如同前面提到的那样,甲方取子节点的最大值,乙方取子节点的最小值。这个评分的函数称作静态估值函数( Static Evaluation function)。用以取代超出固定深度的搜索。显然,我们无法拥有绝对精确的静态估值函数。否则,只要这个静态估值函数就可以解决所有的棋局了。估值函数给出的只是一个较粗略的评分,在此基础上进行的少量搜索的可靠性,理论上是不如前述的WTN,LOST,DRAW三种状态的博弈树的,但这个方法却是可实现的。利用具体的知识构成评估函数的搜索叫做启发式搜索( Heuristic search)。估值函数在有些文献中也称为启发函数(Heuristic Function)

在博弈树搜索的文献当中,极大极小方法往往指的是基于静态估值函数的有限深度的极大极小搜索。在将来使用极大极小方法时如无特别说明也是指这种形式

深度优先搜索( Depth First Search)

在生成极大极小树并对其进行搜索的方法上,我们面临着多种选则

  1. 是先在内存中生成整棵树然后进行搜索,还是在搜索的过程中仅仅产生将要搜索的节
  2. 对于树的搜索以什么顺序进行,是广度优先( Breadth First Search)深度优先,还是其他顺序?
  3. 有必要生成整棵树吗?在搜索过程中将搜索过的节点删去行吗?

几乎所有的人在使用基本的极大极小算法时都选择了深度优先搜索方法。这样可以在搜索过程中的任何时候仅仅生成整棵树的一小部分,搜索过的部分被立即删去。显然,这个算法对内存的要求极低,往往在内存只有几千字节的机器上也可以实现。并且同其他的选择相比速度上也并不逊色。

深度优先搜索极大极小树的过程,可以表示为一个递归的形式。

如图所示的一棵树,共有3层。根节点为A,其子节点有B、C、D三个,而B、C、D也各有子节点若干。以深度优先算法搜索此树时,先进入根节点A,生成其第1个子节点B:然后遍历B,生成B的第1个子节点E;E将其估值返回给父节点B,删掉E,B生成第2个子节点F:F将其估值返回给父节点B,删掉F,B生成第3个子节点G;G将其估值返回给父节点B,删掉G,B在3个叶节点的返回值中取极小值并将此值返回给A, A生成其第2个子节点C:同样遍历C及其子节点,得到C的返回值后再生成D并向下遍历之;最后,A在B、C、D的返回值中取极大值,拥有该极大值的子节点就是下一步要走的方向。

深度优先算法实例

从上述过程可以看出,深度优先搜索极大极小树的过程中,任何时候只要保存与其层数相同个数的节点。在上例中,任何时刻仅需保存3个节点。仅生成将要搜索的节点,搜索完成的节点可以立即删去以节省空间。
用伪代码将深度优先搜索集大极小树算法描述如下:(伪代码仅仅是为说明算法,其内容是简略的)。

代码假定是用于中国象棋

int MiniMax(position p,int d)
{int bestvalue,value;if(Game Over)                     //检测棋局是否结束return evaluation(p);         //棋局结束返回估值if(depth <= 0)                   //是否叶子节点return evalueation(p);      //叶子节点,返回估值if(p.color == RED)              //是否轮到红方走棋bestvalue = -INFINITY;     //是,领初始最大值为极小elsebestvalue = INFINITY;     //否,令初始最小值为极大for(each possibly move m)    //对每一个可能的走法m{MakeMove(m);                //产生第i个局面(子节点)value = MiniMax(p,d-1);    //递归调用MiniMax向下搜索子节点UnMakeMove(m);        //恢复当前局面if(p.color == RED)bestvalue = max(value,bestvalue);  //取最大值elsebestvalue = min(value,bestvalue);  //取最小值}return bestvalue; //返回最大/最小值
}

负极大值算法( Negamax Algorithm)

普通的极大极小值算法看起来有一点笨,既然一方试图取极大值而另一方试图取极小值——也就是说——我们总要检査哪一方要取极大值而哪一方又要取极小值,以执行不同的动作。Knth和More在1975年提出了负极大值( Negamax)方法①,消除了两方的差别,而且简洁优雅。使用负极大值方法,博弈双方都取极大值。
            算法如下面的伪代码所示:
           //类C伪代码,负极大值算法

int NegaMax(position p,int depth)
{int n,value,bestvalue = -INFINITY; //最大值初始为负无穷if(Game Over(p))return evaluation(p);    //胜负已分,返回估值if(depth == 0)  //叶子节点return evaluation(p);    //调用估值函数,返回估值for(each possibly move m)  //对每一个可能的走法{MakeMove(m);   //产生新节点value = -NegaMax(p,d-1);  //递归搜索子节点unMakemove(m);   //撤销新节点if(value >= bestvalue)bestvalue = value; // 取最大值}return bestvalue;   //返回最大值
}

可以看出,负极大值算法比极大极小值算法短小并且简单。关键的不同在于

value=   -NegaMax( p, d-1)

注意其中的负号。负极大值算法的核心在于:父节点的值是各子节点的值的负数的极大值。如要这个算法正确运作,还要注意一点额外的东西。例如象棋,估值函数必须对谁走棋敏感,也就是说对于一个该红方走棋的局面返回正的估值的话,则对于一个该黑方走棋的局面返回负的估值

初看上去,负极大值算法比极大极小值算法稍难理解,但事实上负极大值算法更容易被使用。在算法的原理上,这两种算法完全等效。负极大值算法仅仅是一种更好的表达形式。今天的博弈程序大多采用的也都是基于负极大值形式的搜索算法。本书的例子也不例外。

内容来源于:陈其的《PC游戏编程》(人机博弈)

基本搜索技术--人机博弈算法(极大极小,深度优先,负极大值)相关推荐

  1. 【Qt象棋游戏】07_人机博弈算法开端

    文章目录 01 - 人机博弈算法简述 02 - 相关成员与方法 03 - 获取电脑棋子能走路径 04 - 电脑走棋 05 - 总结 01 - 人机博弈算法简述   前面详细介绍了棋盘类的封装.棋子类的 ...

  2. 白话Elasticsearch24- 深度探秘搜索技术之TFIDF算法/向量空间模型算法/lucene的相关度分数算法

    文章目录 概述 boolean model TF/IDF TF: term frequency IDF:inversed document frequency length norm vector s ...

  3. 基本搜索技术--博弈树

    前言: 假定你的房间里铺有100块地板,其中一块底下有一块金砖,而另一块底下有一颗地雷.如果你翻开有金砖的那块地板,你就可以成为百万富翁:如果你翻开有地雷的那块地板,你就可以到地狱旅行.在经历了长期煎 ...

  4. 基于QT实现的alpha-beta剪枝算法搜索的象棋人机博弈游戏

    中国象棋是一个古老的而富有智慧的游戏,而中国象棋博弈程序是将计算机知识和中国象棋知识结合起来的一种新型的游戏方式.它以一种全新的人机博弈方式突破了以往传统象棋游戏只能人与人对战的限制,使得这个古老的游 ...

  5. 【Qt象棋游戏】08_人机博弈高阶算法

    文章目录 01 - 极大极小值算法 02 - 电脑和人类所有走棋路径 03 - 走一步看两步 04 - 走一步看多步 04 - 总结 01 - 极大极小值算法   上一期博客介绍了最为简单的人机博弈算 ...

  6. 较高人工智能的人机博弈程序实现(多个算法结合)含C++源码

    较高人工智能的人机博弈程序实现(多个算法结合)含C++源码 本文由恋花蝶最初发表于http://blog.csdn.net/lanphaday 上,您可以转载.引用.打印和分发等,但必须保留本文完整和 ...

  7. 搜索技术【启发式搜索】 - 简介 A* 算法 IDA*算法

    搜索技术[启发式搜索] - 简介 & A* 算法 & IDA*算法 尽管广度优先搜索.深度优先搜索加上有效的剪枝方法,可以解决很多问题,但这两种搜索都是盲目的,它们不管目标在哪里,只管 ...

  8. [算法]DFS(深度优先搜索)C++

    1.DFS简介 深度优先搜索(Depth First Search)一种用于遍历或搜索树或图的算法. 沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当节点v的所在边都己被探寻过或者在搜寻时结点不满 ...

  9. 自然语言处理技术(NLP)在推荐系统中的应用 原2017.06.29人工智能头条 作者: 张相於,58集团算法架构师,转转搜索推荐部负责人,负责搜索、推荐以及算法相关工作。多年来主要从事推荐系统以及机

    自然语言处理技术(NLP)在推荐系统中的应用 原2017.06.29人工智能头条 作者: 张相於,58集团算法架构师,转转搜索推荐部负责人,负责搜索.推荐以及算法相关工作.多年来主要从事推荐系统以及机 ...

最新文章

  1. 为何多线程就能提高Java程序的执行效率
  2. android 刷机 备份,安卓刷机后如何还原以前ROM和系统备份
  3. SaltStack 安装、简单配置和远程执行
  4. 直播开发项目发展下半场,转战AI直播开启全新模式
  5. html表单所有类型,表单form的type种类
  6. 电视墙服务器应用,电视墙服务器技术概述
  7. Oracle 已命名的异常
  8. Troubleshooting OpenStack 瘫痪 - 每天5分钟玩转 OpenStack(160)
  9. centos7安装源疯了_Jenkins 在 Centos7 上安装(使用国内源)
  10. Java语法基础常见疑惑解答
  11. VMwareWorkstation下载链接
  12. NAR:eggNOG 5—蛋白功能层级注释数据库
  13. 关于《JavaScript百炼成仙》电子版,在线阅读地址~
  14. js动态显示实时时间
  15. word小技巧 将图片批量居中
  16. 转:陈佩斯曝光春晚背后种种肮脏行径
  17. vant上传图片 转二进制_土旦:移动端 Vue+Vant 的Uploader 实现 :上传、压缩、旋转图片-Go语言中文社区...
  18. Alios things资料篇
  19. EPLAN 设备选择
  20. 3--表格table 个人简历

热门文章

  1. jquery easyui二次开发总结(二)
  2. 异常解决:cococaption包出现找不到edu.stanford.nlp.semgraph.semgrex.SemgrexPattern错误
  3. 推荐35个非常有创意的404错误页面
  4. redisclient工具个人理解
  5. java微信扫码登录代码在这里
  6. 搞数仓也得懂几个常用机器学习算法
  7. Elasticsearch:创建 Ingest pipeline
  8. Docker软件安装文档
  9. Word Averaging模型做文本分类 稳定效果好模型简单
  10. hulu技术宣讲|西安电子科技大学专场