前言

在一些复杂的博弈论题目中,每一轮操作都可能有许多决策,于是就会形成一棵庞大的博弈树

而有一些博弈论题没有什么规律,针对这样的问题,我们就需要用一些十分玄学的算法。

例如对抗搜索

对抗搜索简介

一、 对抗搜索的适用范围

在博弈论题目中,如果决策双方的获胜条件是截然相反的,即一方要求得分越高越好,另一方要求得分越低越好,这时我们就可以用上对抗搜索算法。

二、对抗搜索的主要思想

对抗搜索的核心思想就是\(dfs\)遍历一遍博弈树。

不难想到,如果博弈树非常庞大,在不加优化的情况下,对抗搜索的时间效率是十分低下的。

因此,我们就需要对对抗搜索进行一定的优化。

三、对抗搜索的优化

对抗搜索的优化一般来讲有两种:记忆化\(Alpha-Beta\)剪枝

不过需要注意,如果两个优化一起使用,很可能会产生化学反应出现一些奇妙的\(Bug\)(我已经亲身体验过了)。

对抗搜索优化一:记忆化

记忆化应该是搜索中一个比较常用的技巧。

一、大致思路

它的大致思路就是,对于当前的某一种状态,在求解后将结果记录下来,下一次再访问到时直接将存下来的结果返回即可。

二、模板

记忆化优化对抗搜索的伪代码如下:

inline int dfs(Status s,int Which)//Status记录当前状态,Which记录当前操作的选手,其中0号选手取Max,1号选手取Min
{
if(res[s]) return res[s];//如果之前已经求出过这个状态的结果,直接返回
if(IsEnd(s)) return GetVal(s);//如果当前状态已经为最终状态,就返回当前状态的分值
register int i,ans=Which?1e9:0;
extend(s);//扩展当前状态,并将新状态存储于NewStatus数组中,用NewStatusTotal记录新状态的数量
for(i=1;i<=NewStatusTotal;++i)//枚举从当前状态能够扩展到的新状态
ans=Which?min(ans,dfs(NewStatus[i],Which^1):max(ans,dfs(NewStatus[i],Which^1);//不断dfs,更新ans
return res[s]=ans;//将最终求解出的结果存储下来
}

对抗搜索优化二:\(Alpha-Beta\)剪枝

\(Alpha-Beta\)剪枝应该是对抗搜索一个比较巧妙的优化。

一、大致思路

如图是一棵博弈树

假设第一个决策者的目的是取最大值,第二个决策者的目的是取最小值。

在搜索完根节点的两个子节点后,博弈树就会变成这样:

这时,我们再来看根节点的第三个子节点。

不难发现,在处理完第三个节点的第一个子节点之后,第三个节点的权值就会变成\(2\)。

因为第三个节点的目标是取最小值,因此最终第三个节点的权值必定小于等于\(2\)。

而根节点的目标是取最大值,且此时根节点的权值已经为\(3\)了。

也就是说,第三个节点对最终答案肯定是没有任何贡献的。

因此对于第三个节点的剩余两个状态,我们就无需继续搜索了,可以直接退出。

这就是传说中的\(Alpha-Beta\)剪枝了。

二、模板

\(Alpha-Beta\)剪枝优化对抗搜索的伪代码如下:

inline int dfs(Status s,int Alpha,int Beta,int Which)//Status记录当前状态,Which记录当前操作的选手,其中0号选手取Max,1号选手取Min
//Alpha存储较大值,Beta存储较小值
//如果当前节点是取Max的节点,则Alpha表示当前节点父亲的父亲的权值,Beta表示当前节点父亲的权值
//如果当前节点是取Min的节点,则Alpha表示当前节点父亲的权值,Beta表示当前节点父亲的父亲的权值
{
if(IsEnd(s)) return GetVal(s);//如果当前状态已经为最终状态,就返回当前状态的分值
register int i;
extend(s);//扩展当前状态,并将新状态存储于NewStatus数组中,用NewStatusTotal记录新状态的数量
for(i=1;i<=NewStatusTotal;++i)//枚举从当前状态能够扩展到的新状态
{
t=dfs(NewStatus,Alpha,Beta,Which^1);//求出当前枚举到的新状态的分值
(s.Which?Beta=min(Beta,t):Alpha=max(Alpha,t)); //如果当前节点取min,就更新Beta,否则更新Alpha
if(Alpha>=Beta) break;//如果Alpha≥Beta,就说明这个节点对最终答案没有贡献了,就结束搜索
}
return s.Which?Beta:Alpha;//返回相应值
}

后记

对抗搜索的核心内容差不多也就是这些。

但是,如果真正用起来,对抗搜索其实还是挺复杂的。

下面推荐一道例题:【BZOJ3106】[CQOI2013] 棋盘游戏

博弈论经典算法(一)——对抗搜索与Alpha-Beta剪枝的更多相关文章

  1. CCF(棋局评估)博弈论+对抗搜索+DFS

    201803-4 棋局评估 这题主要使用对抗搜索,也就是每一步寻找可以下棋的位置,通过在这一步下棋看最后会取的什么样的分数. #include<iostream> #include< ...

  2. 机器学习经典算法详解及Python实现--基于SMO的SVM分类器

    原文:http://blog.csdn.net/suipingsp/article/details/41645779 支持向量机基本上是最好的有监督学习算法,因其英文名为support vector  ...

  3. 经典算法题每日演练——第十七题 Dijkstra算法

    原文:经典算法题每日演练--第十七题 Dijkstra算法 或许在生活中,经常会碰到针对某一个问题,在众多的限制条件下,如何去寻找一个最优解?可能大家想到了很多诸如“线性规划”,“动态规划” 这些经典 ...

  4. 经典算法研究系列:二、Dijkstra 算法初探

    July   二零一一年一月 本文主要参考:算法导论 第二版.维基百科. 一.Dijkstra 算法的介绍 Dijkstra 算法,又叫迪科斯彻算法(Dijkstra),算法解决的是有向图中单个源点到 ...

  5. 算法笔记--极大极小搜索及alpha-beta剪枝

    参考1:https://www.zhihu.com/question/27221568 参考2:https://blog.csdn.net/hzk_cpp/article/details/792757 ...

  6. Python3入门机器学习经典算法与应用

    <Python3入门机器学习经典算法与应用> 章节第1章 欢迎来到 Python3 玩转机器学习1-1 什么是机器学习1-2 课程涵盖的内容和理念1-3 课程所使用的主要技术栈第2章 机器 ...

  7. [经典算法题]寻找数组中第K大的数的方法总结

    [经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26   字体:[大 中 小] 打印复制链接我要评论   今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...

  8. 经典算法mark

    在平时找工作的时候,或多或少会遇到一些算法问题,很多都是比较经典或者网上已经流传很久的.只是我们没有接触过,所以不知道怎么解决. 在这儿,我自己总结一些我遇到的一些经典算法,给自己增加一点记忆,也给需 ...

  9. Python3入门机器学习经典算法与应用☝☝☝

    Python3入门机器学习经典算法与应用 (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌) 使用新版python3语言和流行的scikit-learn框架,算法与 ...

随机推荐

  1. 深入理解C/C++ [Deep C (and C++)]

    编程是困难的,正确的使用C/C++编程尤其困难.确实,不管是C还是C++,很难看到那种良好定义并且编写规范的代码.为什么专业的程序员写出这样的代码?因为绝大部分程序员都没有深刻的理解他们所使用的语言. ...

  2. jQuery easyUI id选择器 类选择器 标签选择器 属性选择器 及DOM对象和jQuery相互之间的转换

    首先导入js文件 <%@ page language="java" contentType="text/html; charset=UTF-8" page ...

  3. webpack前端自动化构建工具

    博主不易,不求赞赏,希望把自己遇到的难点写出来,以及希望自己能有能力写出一篇不错的博文. 前端构建工具本人 bootstrap+jquery用gulp vue+element 用webpack 本人最 ...

  4. [Leetcode]007. Reverse Integer

    public class Solution { public int reverse(int x) { long rev=0; while(x!=0){ rev = rev*10+x%10; x=x/ ...

  5. PHPExcel探索之旅---阶段三 绘制图表

    利用PHPExcel插件进行绘制图表 <?php /** * 使用PHPExcel插件在excel文件中利用其中的数据建立折线图 * */ $dir = dirname(__FILE__); r ...

  6. Hadoop实战:微博数据分析

    项目需求 自定义输入格式,将明星微博数据排序后按粉丝数 关注数 微博数 分别输出到不同文件中. 数据集 下面是部分数据,猛戳此链接下载完整数据集 数据格式: 明星   明星微博名称    粉丝数    ...

  7. Hadoop实战:用Hadoop处理Excel通话记录

    项目需求 有博主与家庭成员之间的通话记录一份,存储在Excel文件中,如下面的数据集所示.我们需要基于这份数据,统计每个月每个家庭成员给自己打电话的次数,并按月份输出到不同文件夹. 数据集 下面是部分 ...

  8. JNA-调用win32 Dll文件

    1. 描述备注 参考地址1 JNA示例代码 1.1 JNA工作原理 JNA是建立在JNI技术基础之上的一个Java类库,它使您可以方便地使用java直接访问动态链接库中的函数. 原来使用JNI,你必须 ...

  9. windows 安装python

    前言: Windows 中直接使用Python真的是心累 安装vs 2017(最好是最新版的, 因为python依赖于一些vs提供的包) 下载最新的python的安装程序 安装完毕之后, 不像Linu ...

  10. JS展示预览PDF。

    刚好遇到需求,需要在手机端--展示一个电子收据,电子收据返回是PDF格式的,所以需要在前端上面去做PDF预览. 在学习过程中,了解到一种很简单,不需要任何插件的方法做PDF预览,但是这方法有局限性. ...