Nim游戏的概述:算法
还记得这个游戏吗?
给出n列珍珠,两人轮流取珍珠,每次在某一列中取至少1颗珍珠,但不能在两列中取。最后拿光珍珠的人输。
后来,在一份资料上看到,这种游戏称为“拈(Nim)”。听说,它源自中国,经由被贩卖到美洲的奴工们外传。辛苦的工人们,在工做闲暇之余,用石头玩游戏以排遣寂寞。后来流传到高级人士,则用便士(Pennies),在酒吧柜台上玩。
最有名的玩法,是把十二枚便士放成三、四、5三列,拿光铜板的人赢。后来,你们发现,先取的人只要在3那列里取走2枚,变成了一、四、5,就能稳操胜券了,游戏也就变得无趣了。因而你们就增长列数,增长铜板的数量,这样就让人们有了毫无规律的感受,不易于把握。
直到本世纪初,哈佛大学数学系副教授查理士•理昂纳德•包顿(Chales Leonard Bouton)提出一篇极详尽的分析和证实,利用数的二进制表示法,解答了这个游戏的通常法则。
通常规则是规定拿光铜板的人赢。
它的变体是规定拿光铜板的人输,只要注意某种特殊形态(只有1列不为1),就能够了!
有不少人把这个方法写成计算机程序,来和人对抗,不知就理的人被骗得团团转,无不惊叹计算机的神奇伟大。其实说穿了,只由于它计算比人快,数的转化为二进制其速度快得非人能比,如此罢了。
(以上来自K12教育论坛)dom
Nim游戏的数学理论论述:post
Nim游戏是博弈论中最经典的模型,它又有着十分简单的规则和无比优美的结论
Nim游戏是组合游戏(Combinatorial Games)的一种,准确来讲,属于“Impartial Combinatorial Games”(如下简称ICG)。知足如下条件的游戏是ICG(可能不太严谨):一、有两名选手;二、两名选手交替对游戏进行移动(move),每次一步,选手能够在(通常而言)有限的合法移动集合中任选一种进行移动;三、对于游戏的任何一种可能的局面,合法的移动集合只取决于这个局面自己,不取决于轮到哪名选手操做、之前的任何操做、骰子的点数或者其它什么因素; 四、若是轮到某名选手移动,且这个局面的合法的移动集合为空(也就是说此时没法进行移动),则这名选手负。根据这个定义,不少平常的游戏并不是ICG。例如象棋就不知足条件3,由于红方只能移动红子,黑方只能移动黑子,合法的移动集合取决于轮到哪名选手操做。
一般的Nim游戏的定义是这样的:有若干堆石子,每堆石子的数量都是有限的,合法的移动是“选择一堆石子并拿走若干颗(不能不拿)”,若是轮到某我的时全部的石子堆都已经被拿空了,则判负(由于他此刻没有任何合法的移动)。
这游戏看上去有点复杂,先从简单状况开始研究吧。若是轮到你的时候,只剩下一堆石子,那么此时的必胜策略确定是把这堆石子所有拿完一颗也不给对手剩,而后对手就输了。若是剩下两堆不相等的石子,必胜策略是经过取多的一堆的石子将两堆石子变得相等,之后若是对手在某一堆里拿若干颗,你就能够在另外一堆中拿一样多的颗数,直至胜利。若是你面对的是两堆相等的石子,那么此时你是没有任何须胜策略的,反而对手能够遵循上面的策略保证必胜。若是是三堆石子……好像已经很难分析了,看来咱们必需要借助一些其它好用的(最好是程式化的)分析方法了,或者说,咱们最好可以设计出一种在有必胜策略时就能找到必胜策略的算法。
定义P-position和N-position,其中P表明Previous,N表明Next。直观的说,上一次move的人有必胜策略的局面是P-position,也就是“后手可保证必胜”或者“先手必败”,如今轮到move的人有必胜策略的局面是N-position,也就是“先手可保证必胜”。更严谨的定义是:1.没法进行任何移动的局面(也就是terminal position)是P-position;2.能够移动到P-position的局面是N-position;3.全部移动都致使N-position的局面是P-position。
按照这个定义,若是局面不可能重现,或者说positions的集合能够进行拓扑排序,那么每一个position或者是P-position或者是N-position,并且能够经过定义计算出来。
以Nim游戏为例来进行一下计算。好比说我刚才说当只有两堆石子且两堆石子数量相等时后手有必胜策略,也就是这是一个P-position,下面咱们依靠定义证实一下(3,3)是一个P是一个P是一个P-position。首先(3,3)的子局面(也就是经过合法移动能够致使的局面)有(0,3)(1,3)(2,3)(显然交换石子堆的位置不影响其性质,因此把(x,y)和(y,x)当作同一种局面),只须要计算出这三种局面的性质就能够了。 (0,3)的子局面有(0,0)、(0,1)、(0,2),其中(0,0)显然是P-position,因此(0,3)是N-position(只要找到一个是P-position的子局面就能说明是N-position)。(1,3)的后继中(1,1)是P-position(由于(1,1)的惟一子局面(0,1)是N-position),因此(1,3)也是N-position。一样能够证实(2,3)是N-position。因此(3,3)的全部子局面都是N-position,它就是P-position。经过一点简单的数学概括,能够严格的证实“有两堆石子时的局面是P-position当且仅当这两堆石子的数目相等”。
根据上面这个过程,能够获得一个递归的算法——对于当前的局面,递归计算它的全部子局面的性质,若是存在某个子局面是P-position,那么向这个子局面的移动就是必胜策略。固然,可能你已经敏锐地看出有大量的重叠子问题,因此能够用DP或者记忆化搜索的方法以提升效率。但问题是,利用这个算法,对于某个Nim游戏的局面(a1,a2,...,an)来讲,要想判断它的性质以及找出必胜策略,须要计算O(a1*a2*...*an)个局面的性质,无论怎样记忆化都没法下降这个时间复杂度。因此咱们须要更高效的判断Nim游戏的局面的性质的方法。
直接说结论好了。spa
(Bouton's Theorem):对于一个Nim游戏的局面(a1,a2,...,an),它是P-position当且仅当a1^a2^...^an=0,其中^表示异或(xor)运算。设计
怎么样,是否是很神奇?我看到它的时候也以为很神奇,彻底没有道理的和异或运算扯上了关系。但这个定理的证实却也不复杂,基本上就是按照两种position的证实来的。
根据定义,证实一种判断position的性质的方法的正确性,只需证实三个命题: 一、这个判断将全部terminal position判为P-position;二、根据这个判断被判为N-position的局面必定能够移动到某个P-position;三、根据这个判断被判为P-position的局面没法移动到某个P-position。
第一个命题显然,terminal position只有一个,就是全0,异或仍然是0。
第二个命题,对于某个局面(a1,a2,...,an),若a1^a2^...^an!=0,必定存在某个合法的移动,将ai改变成ai'后知足a1^a2^...^ai'^...^an=0。不妨设a1^a2^...^an=k,则必定存在某个ai,它的二进制表示在k的最高位上是1(不然k的最高位那个1是怎么获得的)。这时ai^k<ai必定成立。则咱们能够将ai改变成ai'=ai^k,此时a1^a2^...^ai'^...^an=a1^a2^...^an^k=0。
第三个命题,对于某个局面(a1,a2,...,an),若a1^a2^...^an=0,必定不存在某个合法的移动,将ai改变成ai'后知足a1^a2^...^ai'^...^an=0。由于异或运算知足消去率,由a1^a2^...^an=a1^a2^...^ai'^...^an能够获得ai=ai'。因此将ai改变成ai'不是一个合法的移动。证毕。
根据这个定理,咱们能够在O(n)的时间内判断一个Nim的局面的性质,且若是它是N-position,也能够在O(n)的时间内找到全部的必胜策略。Nim问题就这样基本上完美的解决了。orm
(以上来自百度百科)blog
Nim游戏的形象具体论述:排序
as + bs + … + ms 是偶数
a1 + b1 + … + m1 是偶数
a0 + b0 + … + m0是偶数
23 = 8 |
22 = 4 |
21 = 2 |
20 = 1 |
|
大小为7的堆
|
0
|
1
|
1
|
1
|
大小为9的堆
|
1
|
0
|
0
|
1
|
大小为12的堆
|
1
|
1
|
0
|
0
|
大小为15的堆
|
1
|
1
|
1
|
1
|
23 = 8 |
22 = 4 |
21 = 2 |
20 = 1 |
|
大小为7的堆
|
0
|
1
|
1
|
1
|
大小为9的堆
|
1
|
0
|
0
|
1
|
大小为12的堆
|
0
|
0
|
0
|
1
|
大小为15的堆
|
1
|
1
|
1
|
1
|
归根结底,Nim取子游戏的关键在于游戏开始时游戏处于何种状态(平衡或非平衡)和第一个游戏人是否可以按照取子游戏的获胜策略来进行游戏。
(以上转自Rainco_shnu的百度空间)
下面写点本身的东西:
若是Nim游戏中的规则稍微变更一下,每次最多只能取K个,怎么处理?
方法是将每堆石子数mod (k+1).