写这篇博客之前,花了许久时间来搞这个SG函数,倒是各路大神的论文看的多,却到底没几个看懂的。还好网上一些大牛博客还是性价比相当高的,多少理解了些,也自己通过做一些题加深了下了解。

既然是博弈,经典的NIM游戏不得不提一下,这也是要不断提醒自己别忘了NIM游戏才是SG函数由来的核心关键!

  1. 若干堆石头。

  2. 甲和乙轮流从任意堆中取任意个石头。

  3. 谁不能取就输。

分析:

  对于一个博弈来说,P-position表示previous,代表先手必败,即后手必胜,N-position表示next,代表先手必胜,后手必败。

  两个博弈的结论:

    若当前状态为N,至少存在下一个能达到的状态是P。(1)

    若当前状态为P,则所有下一个能达到的状态是N。(2)

  显然(0, 0, ..., 0)为必胜态N

凭借这样,因此我们可以通过记忆化搜索可以搜出答案,但是时间复杂度是n!级别的。因此需要更高效的方法来解决NIM问题。

》》》Bouton's Theorem

  对于一个Nim游戏的局面(a1, a2, ..., an),它是P-position当且仅当a1 xor a2 xor... xor an=0

简要证明:

  显然(0, 0, ..., 0)为必败态。

  可归纳证明

  A)对于P-position局面(a1, a2, ..., an)满足a1 xor a2 xor... xor an=0,对于所有合法的移动,

      不妨设为新局面(a1-x, a2, ..., an),则

          (a1-x) xor a2 xor ... xor an

          =(a1-x) xor a2 xor ... xor an xor a1 xor a1

          =(a1-x) xor a1!=0(其中a1>x)。

      故满足结论(2)

  B)对于N-position局面满足a1 xor a2 xor... xor an=k!=0,则存在一个移动使得新局面(a1', a2', ..., an')有a1' xor a2' xor... xor an'=0。因为{ak}中存在ai的二进制在k的最高位上为1,否则k的最高位不能得到,将ai变为ai xor k(<ai),有 a1 xor a2 xor ... xor an xor ai xor k = 0。

      故满足结论(1)

  故若Nim游戏局面满足博弈的两个结论,故存在必胜/必败态及必胜态的必胜步骤。

至此,Nim游戏得到基本解决。

接下来才是重头菜!

  引入SG函数,SG(x)=mex{SG(y) | x->y },其实就是状态x能转移到y。

  SG是表示当前局面的状态(a1,a2,...,an)的一种状态(自然数集合)的函数。有点晕—。—

  mex(Y)表示非Y集合中最小的自然数。例如mex(0,2)=1,mex(1,3)=0。

  此前每次看到很多相关博客引入SG函数都很突兀,凭什么要这样定义mex(),还有SG到底是什么东西?而后都是好像以这两个为基础给出SG的性质,证明之类,看得也似懂非懂。我也不能十分保证我能够讲明白这个高深的理论,如果发现有错,欢迎大牛们指正!

  还是从Nim游戏引入一下这个SG,或者说SG的核心就是Nim游戏,先看看有什么作用。

  (如果发现看不太懂,回去看看SG的定义)

 只考虑一堆石头的情况,

   SG(0)=0(因为(0)没有后继,所以自然SG(0)=0)

   SG(1)=mex(SG(0)=0)=1

   SG(2)=mex(SG(0)=0,SG(1)=1)=2

   ...

   SG(n)=n

 当然一维Nim游戏比较特殊,才有SG(n)=n

 考虑两堆的话,

   SG(0,0)=0

   SG(1,0)=SG(0,1)=mex(SG(0,0)=0)=1

   SG(2,0)=SG(0,2)=mex(SG(0,0)=0,SG(1,0)=1)=2

   SG(1,1)=mex(SG(0,1)=1)=0  //开始有点感觉了吗?

   SG(2,1)=SG(1,2)=mex(SG(1,1)=0,SG(2,0)=2,SG(0,1)=1)=3

   ...

 从二维的数据上可以归纳出,SG(a,b)=a^b

 更多的,想必也能猜出来吧,其实就是之前讨论Nim游戏的结论,所以我才斗胆说SG核心来源于Nim,事实真相倒是不大清楚,相关中文资料确实少。

  想必现在应该有点感觉吧,SG的本质应该是将n维Nim游戏映射到1维Nim游戏。

  想想,每个n维状态对应的1维状态SG,则其状态就和1维相同,可以变为SG-1,SG-2,,,,,1,0,故先手每次都可以将其变成0,而这相当于这一次的1维Nim游戏胜利,而只要能把这个状态保持下去,那么最终就一定能够胜利,也就是说n维Nim游戏就赢了。

  此外异或这真是很神奇的运算。

至此,Nim游戏的结论已经是毋庸置疑,而SG的含义也明白了,而SG的求法却有些模糊,为什么SG(x)=mex(SG(y) | x->y) ?

  要注意到,SG函数的应用远远不局限于Nim游戏,Nim游戏只是SG的一个根基吧?拓展出来的问题更是千变万化。

  我们先来看一个看似更为普遍的问题,实际上是Nim游戏的变性。

    对于有向无环图,一个起点处有一个棋子,两个人轮流移动棋子一步,谁先到达终点谁就胜利。

  我们依然套用SG函数模型(SG(x)=mex(SG(y) | x->y) )来看,(现在状态x就是棋子所在位置)

  SG函数应该满足一下两个条件:

    A)SG(x)为0当且仅当当前局面x为P-position

    B)SG(x)不为0当且仅当当前局面x为N-position

  要注意到SG函数是递归求出来的

  若单纯从该有向图博弈游戏来看,满足

    a)若SG(x)=b!=0,对于任意a∈N && a<b,均存在节点x能够达到的节点y满足SG(y)=a (从SG定义可知)

    b)若SG(x)=b,若x为终点,则当前局面为P-position

            若x非终点,则对于任意节点x能够到达的节点y满足SG(x)!=b

  因此只需递归算出起点的SG值,接着判断起点的SG是否为0,即可判断当前局面是N/P-position。

  可以看出,上述两点都是由SG函数的定义得到,这就是SG函数这样定义的直接原因!当然你可能还是不清楚这样定义的根本原因。

  对于该博弈游戏已经得到解决,但是如果是n个这样的博弈游戏合并起来呢?

    对于有向无环图,n个起点处有棋子,两个人轮流移动一个棋子一步,谁无法移动就失败。

  单单靠SG函数依然是可以计算出来的,但是你实际上还是只用到SG函数是否为0,而对于其SG非0的值的意义没有利用到。

  其实对比Nim游戏模型:

    a)若SG(x)=b,对于任意a∈N && a<b,均存在x能够达到的状态y满足SG(y)=a.

    b)若SG(x)=b,若状态x为(0, 0, ..., 0),则当前局面为P-position

            若状态x非(0, 0, ..., 0),则对于任意x能够达到的状态y,均有SG(y)!=b.

  可以发现上面两个游戏实际上是一致的。

  这样就能够套用Bouton's Theorem对有向图博弈游戏进行运算,即SG(a1,a2,...an)=SG(a1) xor SG(a2) xor ... xor SG(an) ,这才是SG函数如此定义的最终目的,让它能够转化为Nim游戏。

  从而这个博弈问题即可轻松通过n个棋子的SG值进行异或,求出整个游戏的SG值,判断是否为0即可。

  是不是一下子将一个复杂的问题得到大大的简化?

  接下来证明SG(x)在多个博弈游戏组合起来时的一个整体博弈游戏依然满足满足 a)& b):

  首先能转化成Nim游戏模型的游戏,其SG值满足:

    SG(a1,a2,...an)=SG(a1) xor SG(a2) xor ... xor SG(an)

  在这个基础上,

    a)即证明x=(a1, a2, ..., an)=>y=(a1', a2', ..., an')下 有SG(y)=a (所有a∈N && a<b),取k=a xor b,显然存在SG(ai)的二进制在k的最高位上为1,取SG(ai’)=SG(ai) xor k,则SG(a1', a2', ... , an')=SG(a1) xor SG(a2) xor ... xor SG(an) xor k = a 。

    得证

    b) 若b)不成立,则对于任意x,均存在能够达到的状态y,有SG(y)=b,则有 SG(a1) xor SG(a2) xor ... xor SG(an) = 0 ,设状态y为(a1', a2, ..., an) 有 SG(a1') xor SG(a2) xor ... xor SG(an)=b ,由异或满足消去率,a1=a1',与SG定义矛盾。

    得证

  当然上述还需要数学归纳法来证明

  详细的证明参见 王晓珂《解析一类组合游戏》

  小结:

    SG函数的真正目的是将复杂的博弈问题分解成一个个独立的博弈问题之后,通过SG函数将其转化为一个个Nim游戏,然后利用Bouton's Theorem求出整个博弈问题的解。这也就是Sprague-Grundy定理。SG函数的定义就是根据Nim游戏的性质构造出来的一个函数,可以将普通的博弈问题转化为Nim问题,而Nim问题一定有解,故相应博弈问题也一定有解。

这些题目进行巩固以加深了解博弈论知识》》》博弈论相关题目

除此之外,今后还将继续更新此文,扩充一些必要的拓展。

推荐的几篇相关大牛博客(比起那些生涩的论文好太多):

  SG函数闲扯--ydc的日志

  博弈论(二):Sprague-Grundy 函数定理

必读论文:

  王晓珂《解析一类组合游戏》

  《GAME THEORY》——Thomas S. Ferguson

Nim游戏与SG函数 ——博弈论小结的更多相关文章

  1. Nim 游戏、SG 函数、游戏的和

    Nim游戏 Nim游戏定义 Nim游戏是组合游戏(Combinatorial Games)的一种,准确来说,属于“Impartial Combinatorial Games”(以下简称ICG).满足以 ...

  2. [您有新的未分配科技点]博弈论入门:被博弈论支配的恐惧(Nim游戏,SG函数)

    今天初步学习了一下博弈论……感觉真的是好精妙啊……希望这篇博客可以帮助到和我一样刚学习博弈论的同学们. 博弈论,又被称为对策论,被用于考虑游戏中个体的预测行为和实际行为,并研究他们的应用策略.(其实这 ...

  3. 博弈论(nim游戏,SG函数)

    说到自己,就是个笑话.思考问题从不清晰,sg函数的问题证明方法就在眼前可却要弃掉.不过自己理解的也并不透彻,做题也不太行.耳边时不时会想起alf的:"行不行!" 基本的小概念 这里 ...

  4. 数学:Nim游戏和SG函数

    有若干堆石子,两人轮流从中取石子,取走最后一个石子的人为胜利者 以下的性质是显然的 .无法移动的状态是必败态 .可以移动到必败态的局面一定是非必败态 .在必败态做所有操作的结果都是非必败态 在普通Ni ...

  5. 【BZOJ1299】巧克力棒(Nim游戏,SG函数)

    题意:TBL和X用巧克力棒玩游戏.每次一人可以从盒子里取出若干条巧克力棒,或是将一根取出的巧克力棒吃掉正整数长度. TBL先手两人轮流,无法操作的人输. 他们以最佳策略一共进行了10轮(每次一盒).你 ...

  6. hihoCoder hiho一下 第四十六周 博弈游戏·Nim游戏·三( sg函数 )

    题意: 给出几堆石子数量,每次可以取走一堆中任意数量的石头,也可以将一堆分成两堆,而不取.最后取走者胜. 思路: 先规矩地计算出sg值,再对每个数量查SG值就可以了.最后求异或和.和不为0的就是必赢. ...

  7. Nim 博弈和 sg 函数

    sg 函数 参考 通俗易懂 论文 几类经典的博弈问题 阶梯博弈: 只考虑奇数号楼梯Nim,若偶数楼梯只作容器,那么游戏变为Nim.题目 翻转硬币: 局面的SG值为局面中每个正面朝上的棋子单一存在时的S ...

  8. HDU 1864 Brave Game 【组合游戏,SG函数】

    简单取石子游戏,SG函数的简单应用. 有时间将Nim和.SG函数总结一下……暂且搁置. #include <cstdio> #include <cstring> #define ...

  9. BZOJ_3105_[cqoi2013]新Nim游戏_线性基+博弈论

    BZOJ_3105_[cqoi2013]新Nim游戏_线性基+博弈论 Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作 ...

随机推荐

  1. The Jordan 3lab5 is the perfect sneaker for you

    The Jordan 5 3Lab5 Metallic Silver returns inside a mind-turning new iteration for that Spring/Summe ...

  2. win8.1 设置默认输入法为英文

    win8.1中文版 输入法默认为微软拼音且为中文,此事在使用类似cmd就很不方便了,这里我们只需要将输入法设置为 “允许我为每个应用窗口设置不同的输入法”即可,操作如下:

  3. C#如何获取枚举(Enum)变量的值

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Enum ...

  4. 记一次ZOOKEEPER集群超时问题分析

    CDH安装的ZK,三个节点,基本都是默认配置,一直用得正常,今天出现问题,客户端连接超时6倍时长,默认最大会话超时时间是一分钟.原因分析:1.首先要确认网络正确.确认时钟同步.2.查看现有的配置,基本 ...

  5. 【android】activity、fragment传值例子

    1:Activity篇 1.1向Activity传值 关键点在于putExtra.如果传递类的话,记得类实现Serializable接口 Intent intent = new Intent(Firs ...

  6. a=b=c 连等赋值的分析

    首先 先抛出两个例子,大家想想结果是什么? eg1: var a = 1; var b = a; a.x = a = 3; 问 a = ?  |  b = ?  |  a.x = ? eg2: var ...

  7. 服务器抓包命令:tcpdump详解

    官网地址:http://www.tcpdump.org/tcpdump_man.html 简介: tcpdump,就是:dump the traffic on a network,根据使用者的定义对网 ...

  8. 关于URL和http协议,http消息格式

    转自:http://crystal2012.iteye.com/blog/1447845 在WWW(全球资讯网)中想要连结到某个网页,便需要给浏览器一个位址,而URL在此的功能就是告知浏览器某个资源在 ...

  9. svn不提交.net项目中的bin

    1 选中 bin->右击->tortoiseSVN->add to ignore list->选择第二个 2 提交 , 服务器上就没有bin目录了.

  10. 理解 Dubbo SPI 扩展机制

    写在前面 最近接触了 gRPC 体会到虽然众多 RPC 框架各有各的特点但是他们提供的特性和功能有很多的相似之处 , 这就说明他们面对同样的分布式系统带来的问题.从 2016 年左右开始接触到 dub ...