Nim游戏和sg函数

整里如下:



Nim游戏是组合游戏(Combinatorial Games)的一种,准确来说,属于“Impartial Combinatori Games”(以下简称 ICG)。满足以下条件的游戏是ICG(可能不太严谨):

1、有两名选手;
2、两名选手交替对游戏进行移动(move),每次一步,选手可以在(一般而言)有限的合法移动集合中任选一种进行移动;
3、对于游戏的任何一种可能的局面,合法的移动集合只取决于这个局面本身,不取决于轮到哪名选手操作、以前的任何操作、骰子的点数或者其它什么因素;  
4、如果轮到某名选手移动,且这个局面的合法的移动集合为空(也就是说此时无法进行移动),则这名选手负。根据这个定义,很多日常的游戏并非 ICG。例如象棋就不满
足条件3,因为红方只能移动红子,黑方只能移动黑子,合法的移动集合取决于轮到哪名选手操作。 


Nim 游戏
定义:有若干堆石子,每堆石子的数量都是有限的,合法的移动是“选择一堆石子并拿走若干颗(不能不拿)”,如果轮到某个人时所有的石子堆都已经被拿空了,则判负(因为他此刻没有任何合法的移动)。
当然,特殊情况就是只有一堆或者两堆石子,自己去意淫一下吧。


P-position和N-position
其中P 代表Previous,N 代表Next。 P-position是必败态,N-position是必胜态。
必败(必胜)点属性
(1) 所有终结点是必败点(P点); //容易理解
(2) 从任何必胜点(N点)操作,至少有一种方法可以进入必败点(P点); //就是那种我们要走的方法
(3)无论如何操作, 从必败点(P点)都只能进入必胜点(N点).  //对手走完又只能把N留给我们


取子游戏算法实现
步骤1:将所有终结位置标记为必败点(P点);
步骤2: 将所有一步操作能进入必败点(P点)的位置标记为必胜点(N点)
步骤3:如果从某个点开始的所有一步操作都只能进入必胜点(N点) ,则将该点标记为必败点(P点) ;
步骤4: 如果在步骤3未能找到新的必败(P点),则算法终止;否则,返回到步骤2
/*
上面的说法似乎不太好理解。我简单讲下。显然我们可以从终结条件递推回来。往后往前开始扫描,(终结状态方向为后)
a.如果当前是P点,那么一步(向前)可以走到的都是N点
b.如果当前点未标明P/N属性,那么看看该点向后走是不是都只能到达N点,如果是,那么该点是P点。
c.如果该点是N点,倒无法确定什么。
如果没办法标一个点,那么异常结束。
*/


Nim-Sum
直接说结论好了。(Bouton's Theorem)对于一个Nim游戏的局面(a1,a2,...,an),
它是P-position 当且仅当a1^a2^...^an=0,其中^表示异或(xor)运算。


根据定义,证明一种判断position的性质的方法的正确性,只需证明三个命题:  
1、这个判断将所有terminal position 判为P-position;
2、根据这个判断被判为N-position 的局面一定可以移动到某个 P-position;
3、根据这个判断被判为 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'不是一个合法的移动。证毕。
// 简单理解,异或2次可以翻转回来,我们只改一个数字的话,翻不回来。



现在我们来研究一个看上去似乎更为一般的游戏:给定一个有向无环图和一个起始顶点上的一枚棋子,两名选手交替的将这枚棋子沿有向边进行移动,无法移动者判负。事实上,这个游戏可以认为是所有 Impartial Combinatorial Games 的抽象模型。也就是说,任何一个 ICG都可以通过把每个局面看成一个顶点,对每个局面和它的子局面连一条有向边来抽象成这个“有向图游戏”。下面我们就在有向无环图的顶点上定义 Sprague-Garundy函数。
mex(minimal excludant)运算
定义表示最小的不属于这个集合的非负整数。例如mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。 
对于一个给定的有向无环图,定义关于图的每个顶点的 Sprague-Garundy 函数 g 如下:
g(x)=mex{ g(y) | y是 x的后继  }。 


来看一下 SG 函数的性质。首先,所有的 terminal position 所对应的顶点,也就是没有出边的顶点,其 SG 值为 0,因为它的后继集合是空集。然后对于一个g(x)=0 的顶点 x,它的所后继y都满足 g(y)!=0。对于一个g(x)!=0的顶点,必定存在一个后继 y满足g(y)=0。
 

以上这三句话表明,顶点 x 所代表的 postion 是 P-position 当且仅当 g(x)=0(跟P-positioin/N-position 的定义的那三句话是完全对应的)。我们通过计算有向无环图的每个顶点,就可以对每种局面找到必胜策略了。



在看游戏的和之前,我们回到Nim游戏,看看它一堆的时候会是什么情况:我们很容易把一堆石子的情况映射成一个图游戏。其中点v的编号就代表石子数,则存在边(u,v)的条件即(v<u)。
很容易推出来,在这个图中,SG(v) = v的编号;


Nim游戏就是上面这个游戏的一个和。我们有很多个游戏合起来(这里是很多个一堆的Nim游戏),每一次一个游戏者玩哪一个都是可以的(你可以在任何一堆中进行)。不能走的为输。


Nim游戏的结论就是游戏的和的一个重要的结论:对于新游戏的一个状态s = {v1, v2, v3, ... ,vn},其中vi表示在第i个图游戏的状态。有SG(s) = SG(v1) xor SG(v2) xor SG(v3) xor ... xor SG(vn)。
以上结论算是这篇文章的重点。有了这个结论和前述SG函数的性质,便可以解决很多复杂的游戏问题了。


下面先解决上次提出的Nim游戏的一个变形:每一次取石子个数有不超过M的限制,其余规则同Nim-Game试解决这个游戏。


先确定一堆的情况,可得SG(n) = n % m 。然后直接把所有的SG值xor起来即可。


事实上SG函数还有很多很灵活的运用,其基础就是前文叙述的两个结论。
再举一个例子:
有一个楼梯,在楼梯是放上K枚硬币,分布在不同的台阶尚。甲乙两人每次从楼梯中选一级台阶,在其中任选一些棋子移到下面一级。谁不能移动就算输。(第0级不能再往下移)


这个问题其实只要把奇数级楼梯的硬币数xor起来即可。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值