作者:还想养只小短腿
链接:https://www.zhihu.com/question/27221568/answer/140874499
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

先来说极小极大算法主要应用于什么样的游戏:
1. 零和游戏(Zero-sum Game):意思就是你死我活,一方的胜利代表另一方的失败,比如,象棋,五子棋等。
2. 完全信息(Perfect Information):玩家知道之前所有的步骤。象棋就是完全信息,因为玩家是交替着落子,且之前的步骤都能在棋盘上体现,但是石头剪子布就不是。
这样的游戏通常可以把他们看作一个树状图,把每一种可能性列出来。比如下面这个井字棋游戏,Max代表你自己,Min代表你的对手。

这个时候我们需要给每一种结果一个分数,就是这里的Utility。这个分数是站在我自己(也就是Max)的角度评估的,比如上图中我赢了就是+1,输了是-1,平局时0。所以,我希望最大化这个分数,而我的对手希望最小化这个分数。(在游戏中,这个分数被称为static value。)这里要说一下,井字棋是个比较简单的游戏,所以可以列出所有可能的结果。但是,大部分游戏是不太可能把所有结果都列出来的。根据计算机运算量,我们可能只能往前推7,8步,所以这个时候分数就不只-1,1,0这么简单了,会有专门的算法来根据当前结果给不同的分数。
假设我们有如下图的游戏,我是先手,我应该如何利用Minmax算法来选出第一步怎么走呢?

这个时候我们就要从结果看起,也就是第4步。图中标注第四步是我的对手下的,所以他要做的是最小化这个分数,于是对手根据结果可以反推出如下选择

继续从后往前看到第3步,当我们知道了对手的选择以后,我们可以根据对手的结果反推出自己的选择,我们要做的是最大化这个分数,如图

重复这个步骤,我们最终可以发现第一步的最优选择,如图

以上就是极小极大算法(Minimax)。

当然对于一个复杂的游戏来说,比如象棋,肯定是需要非常多步才能完成的。这就导致结果的数量是成几何增长的,也就是说,如果这个游戏每一步都有n个选择,那么在x步以后,将会有n^x个选择。这个时候,我们就需要采取剪枝算法(Alpha-Beta)来减少运算量。从剪枝算法这个名字我们就能看出,这个算法能让我们剪掉树状图中的一些分支,从而减少运算量。在这里也说一下剪枝算法,因为这并不是个不同于极小极大的算法,而是极小极大算法的升级版。
我们将游戏简化成如下图,使用Minimax算法,我们可以得出这样的结果

但是,最后一步的分数其实也需要计算机来算(static evaluation),所以我们并不会一开始就有所有的数据,其实我们一开始是这样的

然后,计算机给出了第一个分数

当给出了这个分数的时候,我们站在步骤1看,无论另一分支的数字是多少,步骤1左边方框的数字不会超过2。因为第2步是我的对手下的,他希望分数尽可能的小,也就是这样的

这个时候,电脑再计算另一分支的分数,也就是7。知道另一分数是7以后,也就知道步骤1的左边方框分数为2。这时,我们往前看一步(步骤0)。步骤0的分数是大于等于2,因为我要最大化分数。如图

现在,再来计算右边分支的分数,得到了1。同理,我们站在步骤1来看,右边方框中的数不会超过1,如图

在这个情况下,即使我不算最后一个数字,我也能知道在步骤0的结果为2,因为已知步骤1中的右边方框,数值不会超过1。所以我们就能直接知道结果,也就是

我们可以看到,加上剪枝算法,我们不仅得到了相同的结果,而且减少了计算量。在实际应用中,加上剪枝算法,计算机大约需要算2*n^(x/2)个结果,如果n为分支数,x为步数。相比于之前仅用极小极大算法的n^x,效率提高了很多。这也就意味着,如果在象棋比赛中,假设使用极小极大的算法,计算机能往前评估7步,加上剪枝算法,计算机能往前评估14步。极小极大和剪枝算法曾在IBM开发的国际象棋超级电脑,深蓝(Deep Blue)中被应用,并且两次打败当时的世界国际象棋冠军。

python代码实现:

def minimax(state, depth, player):"""AI function that choice the best move:param state: current state of the board:param depth: node index in the tree (0 <= depth <= 9),but never nine in this case (see iaturn() function):param player: an human or a computer:return: a list with [the best row, best col, best score]"""if player == COMP:best = [-1, -1, -infinity]else:best = [-1, -1, +infinity]if depth == 0 or game_over(state):score = evaluate(state)return [-1, -1, score]for cell in empty_cells(state):x, y = cell[0], cell[1]state[x][y] = playerscore = minimax(state, depth - 1, -player)state[x][y] = 0score[0], score[1] = x, yif player == COMP:if score[2] > best[2]:best = score  # max valueelse:if score[2] < best[2]:best = score  # min valuereturn best

算法学习(一)——Minimax算法相关推荐

  1. Surf算法学习心得(一)——算法原理

    Surf算法学习心得(一)--算法原理 写在前面的话: Surf算法是对Sift算法的一种改进,主要是在算法的执行效率上,比Sift算法来讲运行更快!由于我也是初学者,刚刚才开始研究这个算法,然而网上 ...

  2. 算法学习四:算法性能分析理论基础——函数增长与渐进分析

    算法学习四:算法性能分析理论基础--函数增长与渐进分析 在算法性能分析过程中,特别是在算法运行效率分析中,我们经常使用渐渐分析法,它使我们在分析算法性能时不必纠结于不同硬件平台的差异性,着重考虑算法的 ...

  3. python五子棋算法_python使用minimax算法实现五子棋

    这是一个命令行环境的五子棋程序.使用了minimax算法. 除了百度各个棋型的打分方式,所有代码皆为本人所撸.本程序结构与之前的井字棋.黑白棋一模一样. 有一点小问题,没时间弄了,就这样吧. 一.效果 ...

  4. 令人拍案叫绝的算法学习网站新手算法入门到精通,算法面试冲刺资料这里都有

    (9月已更)学算法认准这6个网站就够了! 写在前面:作为ACM铜牌选手,从FB到腾讯,从事算法&java岗位工作也是5年有余.在工作中接触到了很多同学,在算法学习和算法面试这件事上我还是很有发 ...

  5. 算法学习之模拟退火算法路径规划(python代码实现)

    模拟退火算法路径规划(python代码实现) 一.引言 二.算法介绍以及伪代码 1.算法通俗介绍 2.路径规划算法伪代码 三.算法流程及代码实现 1.地图创建 2.初始化路径 小结 3.计算适应度值 ...

  6. 【算法学习】贪心算法

    参考算导第三版第16章 贪心算法 文章目录 1. 活动选择问题 1.1 活动选择问题的最优子结构 1.2 贪心选择 1.3 递归贪心算法 1.4 迭代贪心算法 2. 贪心算法原理 2.1 贪心选择性质 ...

  7. 令人拍案叫绝的算法学习网站,算法入门到精通,算法面试冲刺资料这里都有

    前言 作为ACM铜牌选手,从FB到腾讯,从事算法&java岗位工作也是5年有余.在工作中接触到了很多同学,在算法学习和算法面试这件事上我还是很有发言权的. 今天就跟想学算法的同学分享一下我私藏 ...

  8. 算法学习————自然归并算法(c/c++)

    自然归并算法实现(c/c++) 前言:由于归并算法的资料已经很多了,本文主要讲述的是自然归并算法 自然归并算法VS归并算法 自然归并算法实际上是归并算法的一个变型. 例如在下文实例代码中的数组a中的元 ...

  9. 通过创建黑白棋机器人来学习实现 Minimax 算法

    介绍 黑白棋程序,我选择开发这个程序是因为在寻找黑白棋/黑白棋游戏时找不到具有我需要的功能的程序. 特征 支持模式 Human vs Human.Human vs Bot.Bot vs Bot 支持板 ...

  10. 数据结构与算法学习③(Hash hash算法的工程应用 递归 )

    Hash Hash 散列表(Hash Table) 概述 散列函数 散列冲突 复杂度分析 工程应用 面试实战 亚马逊,微软最近面试题,242. 有效的字母异位词 腾讯,高盛集团最近面试题,49. 字母 ...

最新文章

  1. 麒麟810怎么样_华为麒麟810这个跑分,让我意外
  2. linux编译安装git
  3. c语言实现结构体变量private,C语言中结构体变量私有化详解
  4. 计算机二级怎么测试c语言,全国计算机等级测试二级C语言视频教程(完整版).doc...
  5. 这8个方法让你成为最优秀的程序员
  6. Java面向对象(20)--接口
  7. python基础(12)之匿名函数lambda
  8. 946. 验证栈序列
  9. 调用restful接口_SSM实现RESTFul风格的CURD操作
  10. 晶圆级封装行业调研报告 - 市场现状分析与发展前景预测
  11. 通过JAVA获取优酷视频
  12. Windows10下VB6.0开发——常用数值处理函数工具
  13. 使用C# WinForm实现打印小票的功能
  14. Android NDK开发如何解决logcat日志打印不全
  15. java坦克大战 素材_坦克大战 游戏源码+ 素材+文档(了解面向对象的具体编程)
  16. 黑塞矩阵和雅克比矩阵
  17. 和平精英android怎么写符号,特殊符号输入方法 和平精英iOS和安卓名字特殊符号...
  18. windows7蓝牙怎么打开_英特尔升级Wi-Fi 和蓝牙驱动,Win10 更新5月版稳了
  19. 【CodeChef-LYRC】Music Lyrics【AC自动机】
  20. android 树莓派 图片,Android Things:树莓派3上手就是这么简单

热门文章

  1. 微信公众号发布和群发的区别是什么?
  2. Python3截图识字工具
  3. msdia80.dll-重装系统后有使用64位win7操作系统的同学注意!
  4. fake-useragent User Agent 伪装
  5. oracle普通索引改唯一索引,Oracle唯一索引功能替代
  6. 烽火通信2018校招软件工程师编程题 - 题解
  7. 科学研究设计七:单案例设计
  8. PHP工具箱配置和下载
  9. GPS经纬度转百度经纬度JAVA
  10. 微信小程之打卡小程序开发