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

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

在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. RHCSA-day3

    10.配置LDAP客户端 在classroom.example.com上已经部署了一台LDAP认证服务器,按以下要求将你的系统加入到该LDAP服务中,并使用Kerberos认证用户密码: 该LDAP认 ...

  2. 1563: [NOI2009]诗人小G

    1563: [NOI2009]诗人小G https://lydsy.com/JudgeOnline/problem.php?id=1563 分析: 直接转移f[i]=f[j]+cost(i,j),co ...

  3. Mac 必备工具之 brew

    brew 是 Mac 下的一个包管理工具,类似于 centos 下的 yum,可以很方便地进行安装/卸载/更新各种软件包,例如:nodejs, elasticsearch, kibana, mysql ...

  4. python进程-进阶

    进程同步(multiprocessing.Lock(锁机制).multiprocessing.Semaphore(信号量机制).multiprocessing.Event(事件机制)) 在计算机中,有 ...

  5. 强化学习读书笔记 - 10 - on-policy控制的近似方法

    强化学习读书笔记 - 10 - on-policy控制的近似方法 学习笔记: Reinforcement Learning: An Introduction, Richard S. Sutton an ...

  6. JMeter:全面的乱码解决方案【转】

    本文是转自https://www.cnblogs.com/mawenqiangios/p/7918583.html 感谢分享者   中文乱码一直都是比较让人棘手的问题,我们在使用Jmeter的过程中, ...

  7. ython进阶06 循环对象

    这一讲的主要目的是为了大家在读Python程序的时候对循环对象有一个基本概念. 循环对象的并不是随着Python的诞生就存在的,但它的发展迅速,特别是Python 3x的时代,循环对象正在成为循环的标 ...

  8. 【数据结构系列】线段树(Segment Tree)

    一.线段树的定义 线段树,又名区间树,是一种二叉搜索树. 那么问题来了,啥是二叉搜索树呢? 对于一棵二叉树,若满足: ①它的左子树不空,则左子树上所有结点的值均小于它的根结点的值 ②若它的右子树不空, ...

  9. IncDec序列:差分+贪心

    IncDec序列 题目描述: 给定一个长度为 n 的数列 a1,a2,…,an,每次可以选择一个区间[l,r],使下标在这个区间内的数都加一或者都减一. 求至少需要多少次操作才能使数列中的所有数都一样 ...

  10. CDQ分治_占坑

    准备系统地学习一波CDQ分治,持续更新中... 首先,CDQ分治也还是分治的一种,只不过普通分治是独立的解决两个子问题,而CDQ分治还要计算第一个子问题对于第二个的影响. CDQ分治几乎都是用来解决多 ...