今天初步学习了一下博弈论……感觉真的是好精妙啊……希望这篇博客可以帮助到和我一样刚学习博弈论的同学们。

博弈论,又被称为对策论,被用于考虑游戏中个体的预测行为和实际行为,并研究他们的应用策略。(其实这句话没有什么卯月)

在OI中,博弈论的主要应用是一些经典的模型,以及sg函数,sj定理的应用。

首先我们来看博弈论最为经典的模型之一:Nim游戏

有n堆石子,每次可以从其中任意一堆石子中取出若干块石子(可以取完),不能不取。

最后无石子可取者为输家。假设两人都按最优情况走,问是否先手必胜。

为了计算这个问题,我们对这些状态定义position,设N-position(now-position)表示先手必胜状态,P-position(pre-position)表示先手必败状态

我们再定义某状态的后继状态为这个状态取走一些石子之后达到的新状态

那么显然,N-position的后继状态一定有一个是P-position,而P-position的后继状态全是N-position

有了这两种定义,我们再来观察Nim游戏:显然,0枚石子是一个P-position,接着,1,2,……inf枚石子都是N-position

而对于两堆,三堆甚至更多的情况,我们只需要考察后继状态是否全为N-position,这样我们就找到了一个计算某个状态是否为必胜状态的方法,利用记忆化搜索判断即可。但是,如果设有n堆石子,他们的个数分别是a1,a2........an,那么搜索的状态数是a1*a2*.....*an种,显然当数据变大的时候这个较为暴力的算法就不优秀了

因此,接下来我们引入一个新的函数来协助我们的运算:sg函数。sg函数,是一种代表游戏局面的函数,其值为0时该状态是必败状态,反之,>0是必胜状态。

在一开始,我们并不知道对于某个游戏的sg()的计算方式是什么,我们只能通过手玩小数据->猜测计算方式->回带验证的方式来计算一个sg()的计算方式

但这些并没有什么卯月仍然没有解决上面Nim游戏中状态过多的问题,因此为了解决它,现在我们先来说结论,下面给出证明:这个状态的#S,等于它所有子游戏T1,T2,....Tn的#T值异或和,即#S=#T1^#T2^....^#Tn

局面为#S>0时,设#S=a1^a2^…^an=d,假设d的二进制最高位为k,那么一定存在至少一个ai第k位为1,显然ai^d<ai。(因为异或后第k位变为0,ai减去2^k,而其它位最多加上2^k-1.)那么只要将ai改变为ai^d,异或和变为d^a1^…^an=d^d=0。即#S>0时一定可以走到一个#T=0的状态。

当游戏为终止局面#S=0时,假设可以将ai变为ai‘,使#T为0.由于#S=a1^…^ai^…^an=0,即ai=a1^…^ai-1^ai+1^…^an。同理得ai’= ai=a1^…^ai-1^ai+1^…^an。这样ai=ai‘,显然矛盾,所以一个#S=0的状态只能到达#T>0。

在有了这个异或操作之后,我们就可以在O(n)时间内求出目标游戏状态的sg值了,只需要把它的子游戏异或起来即可。但注意,异或不是所有的游戏都适用。首先,只有当游戏步数有限,不能移动者输,并且双方公平游戏的时候才能使用。其次,异或只能用于处理子游戏状态的加和。如果某一个状态已经不能继续拆成子游戏了(比如Nim游戏的一堆石子),就不能用异或来求解sg值了,正因为异或有局限性,所以我们需要掌握真正推导sg函数的方法。我们假设已经设出一个sg函数,考虑如何验证。

不难看出,在设某个多堆的石子状态为S,其sg值为#S,其后继状态为T的情况下,使得:若#S=0,则所有#T>0;若#S>0,则存在#T=0。如果这两个状态成立,则刚才规定的sg计算方法是正确的。那么如何求一个正确的sg函数值呢?

为了方便证明,我们设g(S)为状态S的后继状态T的#T的集合。

还用nim游戏的例子来证明,我们设S的n堆石子为a1~an。那么如果#S=0,则#S=sg(a1)^sg(a2)^sg(a3)......^sg(an)=0.我们设这一步的策略是把ai改为ai',则有

sg(ai)=sg(a1)^sg(a2)^sg(a3)..^sg(i-1)^sg(i+1)^...^sg(an),接着#S'=sg(a1)^sg(a2)^sg(a3)....^sg(ai')..^sg(an)=sg(ai')^sg(ai)

显然,ai不等于ai',即#S'>0,命题得证!

如果#S=sg(a1)^sg(a2)^sg(a3)......^sg(an)>0,还是设这一步的策略是把ai改为ai',则有

那么从刚才Nim游戏的证明可以知道,ai'取ai'^#S时为最优策略,这时#T=#S^#S=0.由于ai'^#S<ai并且ai^S#的值并不确定,因此0~sg(a[i])-1属于g(S)

现在,再看看我们得到了什么结论:sg(ai)∉g(S),并且sg(0)~sg(ai-1)∈g(S)。那么,显然这个sg(ai)就是g(S)中最小的未出现自然数(mex操作)啊!

这样的话,我们就可以递推的求sg函数值了。mex的查询可以O(n)扫,也可以O(log2n)用树状数组维护。并且,现在我们就可以证明一些前面证明不了的东西了:比如Nim游戏的sg值为什么是sg(x)=x

证明:显然sg(0)=0,那么sg(1)=mex(sg(0))=mex(0)=1,sg(2)=mex(sg(1),sg(0))=mex(1,0)=2........那么这样就可以看出sg(x)=x了

其他的sg函数值也可以这样算,但一般效率不太高,需要自己定义适合题意的sg函数快捷计算方法,并且证明。

sg函数的基础内容就是这些,接下来还会有sg函数知识的进阶和一些基础题目讲解。今天就到这里:)

[您有新的未分配科技点]博弈论入门:被博弈论支配的恐惧(Nim游戏,SG函数)的更多相关文章

  1. [您有新的未分配科技点] 无旋treap:从单点到区间(例题 BZOJ1500&NOI2005 维护数列 )

    1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MB Description Input 输入的第1 行包含两个数N 和M(M ≤20 ...

  2. [您有新的未分配科技点]博弈论进阶:似乎不那么恐惧了…… (SJ定理,简单的基础模型)

    这次,我们来继续学习博弈论的知识.今天我们会学习更多的基础模型,以及SJ定理的应用. 首先,我们来看博弈论在DAG上的应用.首先来看一个小例子:在一个有向无环图中,有一个棋子从某一个点开始一直向它的出 ...

  3. [您有新的未分配科技点]无旋treap:从好奇到入门(例题:bzoj3224 普通平衡树)

    今天我们来学习一种新的数据结构:无旋treap.它和splay一样支持区间操作,和treap一样简单易懂,同时还支持可持久化. 无旋treap的节点定义和treap一样,都要同时满足树性质和堆性质,我 ...

  4. [您有新的未分配科技点]可,可,可持久化!?------0-1Trie和可持久化Trie普及版讲解

    这一次,我们来了解普通Trie树的变种:0-1Trie以及在其基础上产生的可持久化Trie(其实,普通的Trie也可以可持久化,只是不太常见) 先简单介绍一下0-1Trie:一个0-1Trie节点只有 ...

  5. [您有新的未分配科技点]数位DP:从板子到基础(例题 bzoj1026 windy数 bzoj3131 淘金)

    只会统计数位个数或者某种”符合简单规律”的数并不够……我们需要更多的套路和应用 数位dp中常用的思想是“分类讨论”思想.下面我们就看一道典型的分类讨论例题 1026: [SCOI2009]windy数 ...

  6. [您有新的未分配科技点]数位dp:从懵X到板子(例题:HDU2089 不要62)

    数位dp主要用来处理一系列需要数数的问题,一般套路为“求[l,r]区间内满足要求的数/数位的个数” 要求五花八门……比如“不出现某个数字序列”,“某种数的出现次数”等等…… 面对这种数数题,暴力的想法 ...

  7. [您有新的未分配科技点][BZOJ3545&BZOJ3551]克鲁斯卡尔重构树

    这次我们来搞一个很新奇的知识点:克鲁斯卡尔重构树.它也是一种图,是克鲁斯卡尔算法求最小生成树的升级版首先看下面一个问题:BZOJ3545 Peaks. 在Bytemountains有N座山峰,每座山峰 ...

  8. 博弈论 | 详解搞定组合博弈问题的SG函数

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天这篇是算法与数据结构专题的第27篇文章,我们继续深入博弈论问题.今天我们要介绍博弈论当中非常重要的一个定理和函数,通过它我们可以解决许多 ...

  9. POJ 3553 Light Switching Game 博弈论 nim积 sg函数

    http://poj.org/problem?id=3533 变成三维的nim积..前面hdu那个算二维nim积的题的函数都不用改,多nim积一次就过了...longlong似乎不必要但是还是加上了 ...

随机推荐

  1. 1109: [POI2007]堆积木Klo

    1109: [POI2007]堆积木Klo https://lydsy.com/JudgeOnline/problem.php?id=1109 分析: 首先是dp,f[i]表示到第i个的最优值,f[i ...

  2. 解决非controller使用,@Autowired或者@Resource注解注入Mapper接口为null的问题

    知识点:在service层中注入其它的service接口或者mapper接口都是可以的 但是在封装的Utils工具类中或者非controller普通类中使用@Autowired@Resource注解注 ...

  3. Yii2.0 高级模版编写使用自定义组件(component)

    翻译自:http://www.yiiframework.com/wiki/760/yii-2-0-write-use-a-custom-component-in-yii2-0-advanced-tem ...

  4. new表达式,operator new和placement new介绍

    new/delete是c++中动态构造对象的表达式 ,一般情况下的new/delete都是指的new/delete表达式,这是一个操作符,和sizeof一样,不能改变其意义. new/delete表达 ...

  5. HTTP协议请求信息详解

    通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息.客户端向服务器发送一个请求,请求头包含请求的方法.URI.协议版本.以及包含请求修饰符.客户信息和内容的类似于MIME的消息结构 ...

  6. CentOS7使用阿里源安装最新版Docker

    卸载已经安装的Docker sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker ...

  7. 高可用Kubernetes集群-8. 部署kube-scheduler

    十.部署kube-scheduler kube-scheduler是Kube-Master相关的3个服务之一,是有状态的服务,会修改集群的状态信息. 如果多个master节点上的相关服务同时生效,则会 ...

  8. [leetcode-914-X of a Kind in a Deck of Cards]

    In a deck of cards, each card has an integer written on it. Return true if and only if you can choos ...

  9. 常用的不易记忆的css自定义代码

    在制作页面时,经常会遇到需要自定义一些标签的默认行为(如:input的占位符等),但这些默认的设置的css一般比较难记住,所以有必要自己做一下记录.下面是我经常用到的一些重设默认行为的css. 1.占 ...

  10. Lucky Conversion(找规律)

    Description Petya loves lucky numbers very much. Everybody knows that lucky numbers are positive int ...