Nim游戏与SG函数 ——博弈论小结
写这篇博客之前,花了许久时间来搞这个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问题一定有解,故相应博弈问题也一定有解。
这些题目进行巩固以加深了解博弈论知识》》》博弈论相关题目
除此之外,今后还将继续更新此文,扩充一些必要的拓展。
推荐的几篇相关大牛博客(比起那些生涩的论文好太多):
必读论文:
《GAME THEORY》——Thomas S. Ferguson
Nim游戏与SG函数 ——博弈论小结的更多相关文章
- Nim 游戏、SG 函数、游戏的和
Nim游戏 Nim游戏定义 Nim游戏是组合游戏(Combinatorial Games)的一种,准确来说,属于“Impartial Combinatorial Games”(以下简称ICG).满足以 ...
- [您有新的未分配科技点]博弈论入门:被博弈论支配的恐惧(Nim游戏,SG函数)
今天初步学习了一下博弈论……感觉真的是好精妙啊……希望这篇博客可以帮助到和我一样刚学习博弈论的同学们. 博弈论,又被称为对策论,被用于考虑游戏中个体的预测行为和实际行为,并研究他们的应用策略.(其实这 ...
- 博弈论(nim游戏,SG函数)
说到自己,就是个笑话.思考问题从不清晰,sg函数的问题证明方法就在眼前可却要弃掉.不过自己理解的也并不透彻,做题也不太行.耳边时不时会想起alf的:"行不行!" 基本的小概念 这里 ...
- 数学:Nim游戏和SG函数
有若干堆石子,两人轮流从中取石子,取走最后一个石子的人为胜利者 以下的性质是显然的 .无法移动的状态是必败态 .可以移动到必败态的局面一定是非必败态 .在必败态做所有操作的结果都是非必败态 在普通Ni ...
- 【BZOJ1299】巧克力棒(Nim游戏,SG函数)
题意:TBL和X用巧克力棒玩游戏.每次一人可以从盒子里取出若干条巧克力棒,或是将一根取出的巧克力棒吃掉正整数长度. TBL先手两人轮流,无法操作的人输. 他们以最佳策略一共进行了10轮(每次一盒).你 ...
- hihoCoder hiho一下 第四十六周 博弈游戏·Nim游戏·三( sg函数 )
题意: 给出几堆石子数量,每次可以取走一堆中任意数量的石头,也可以将一堆分成两堆,而不取.最后取走者胜. 思路: 先规矩地计算出sg值,再对每个数量查SG值就可以了.最后求异或和.和不为0的就是必赢. ...
- Nim 博弈和 sg 函数
sg 函数 参考 通俗易懂 论文 几类经典的博弈问题 阶梯博弈: 只考虑奇数号楼梯Nim,若偶数楼梯只作容器,那么游戏变为Nim.题目 翻转硬币: 局面的SG值为局面中每个正面朝上的棋子单一存在时的S ...
- HDU 1864 Brave Game 【组合游戏,SG函数】
简单取石子游戏,SG函数的简单应用. 有时间将Nim和.SG函数总结一下……暂且搁置. #include <cstdio> #include <cstring> #define ...
- BZOJ_3105_[cqoi2013]新Nim游戏_线性基+博弈论
BZOJ_3105_[cqoi2013]新Nim游戏_线性基+博弈论 Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作 ...
随机推荐
- adb push ,adb pull和adb install的区别
1.用命令行把手机上的文件拷贝到电脑上 1 adb pull sdcard/1222073679.png 拷贝文件夹命令,如把log文件夹拷贝到电脑当前目录 1 adb pull sdcard/log ...
- (二)无状态的web应用(单py的Django占位图片服务器)
本文为作者原创,转载请注明出处(http://www.cnblogs.com/mar-q/)by 负赑屃 阅读本文建议了解Django框架的基本工作流程,了解WSGI应用,如果对以上不是很清楚,建议结 ...
- JS:parseInt("08")或parseInt("09")转换返回0的原因
一.parseInt用法 parseInt(s); parseInt(s,radix) 二.第一个方式不再多说,第二个方式,radix是s所基于的进制.范围为2-36(不在此范围函数将返回NaN). ...
- Laravel 文档中的 Service Providers
$this->app->singleton('ReportServices', function () { return new \App\Services\ReportServices( ...
- PKU 3318 Matrix Multiplication(随机化算法||状态压缩)
题目大意:原题链接 给定三个n*n的矩阵A,B,C,验证A*B=C是否成立. 所有解法中因为只测试一组数据,因此没有使用memset清零 Hint中给的傻乎乎的TLE版本: #include<c ...
- 手机端1px细线公共类
手机端1px细线公共类 .borderBottom1px{ position: relative; } .borderBottom1px:after{ content: ""; p ...
- u-boot.cfg转eclipse_xml小脚本
手动复制粘贴版本 cat u-boot.cfg | awk '{if(length($3)){$3 = substr($0, length($1)+length($2)+3); gsub(" ...
- Django学习笔记之利用Form和Ajax实现注册功能
一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面建一个forms.py的文件来存放 2 ...
- CSS 媒体类型
CSS 媒体类型 媒体类型允许你指定文件将如何在不同媒体呈现.该文件可以以不同的方式显示在屏幕上,在纸张上,或听觉浏览器等等. 一.媒体类型 一些CSS属性只设计了某些媒体.例如"voice ...
- 20145329《Java程序设计》第四周学习总结
教材学习内容总结 封装.继承.多态 封装:封装类私有数据,让用户无法直接存取. 继承: 定义:避免多个类间重复定义共同行为,就是相同的代码提升为父类,java中只能继承一个父类.用继承的方式编写代码可 ...