[模板]Nim博弈与SG函数

原文一 原文二

一、Nim游戏

1、引子

  Alice与Bob在玩一个取石子的游戏。 在这个游戏有N堆不同的石子,编号1..N,第i堆中有Ai个石子。 每一次行动,Alice和Bob可以选择从一堆石子中取出任意数量的石子。至少取1颗,至多取出这一堆剩下的所有石子。 Alice和Bob轮流行动,取走最后一个石子的人获得胜利。 假设每一轮游戏都是Alice先行动,请你判断在给定的情况下,如果双方都足够聪明,谁会获得胜利?

2、讨论

这是一个古老而又经典的博弈问题:Nim游戏。

Nim游戏是经典的公平组合游戏ICG(Impartial Combinatorial Games),对于ICG游戏我们有如下定义:

  • 两名选手
  • 两名选手轮流行动,每一次行动可以在有限合法操作集合中选择一个
  • 游戏的任何一种可能的局面(position),合法操作集合只取决于这个局面本身,不取决于轮到哪名选手操作、以前的任何操作、骰子的点数或者其它因素;局面的改变称为“移动”(move)
  • 如果轮到某名选手移动,且这个局面的合法的移动集合为空(也就是说此时无法进行移动),则这名选手失败

对于第三条,我们有更进一步的定义Position,我们将Position分为两类:

  1. P-position:在当前的局面下,先手必败 (P=previous,即前一个人走了之后必胜,即必败局面)
  2. N-position:在当前的局面下,先手必胜 (N=next,即当前选手走了之后必胜,即必胜局面)

它们有如下性质:

  1. 合法操作集合为空的局面是P-position (终止局面,没法走了,为必败局面)
  2. 可以移动到P-position的局面是N-position (能让另一个选手到达必败局面,则当前局面是必胜局面)
  3. 所有移动都只能到N-position的局面是P-position (没法让另一个选手到达必败局面,即无论怎么走对方都必胜,则当前局面为必败局

3、解决

  显然,我们从终止局面向前递推,从而得到每个局面是必胜局面还是必败局面

  但如果石子很多的话,算法复杂度将过大,这里引入一个重要结论Bouton's Theorem

对于一个局面,当且仅当A1 xor A2 xor … xor AN =0时,该局面为必败局面,否则为必胜局面。

证明:

设A1 xor A2 xor … xor AN =k

1、若k=0

①如果无合法操作了,即所有石子数量=0,则为必败局面

②如果还能操作,任取一种都将导致异或和变成≠0 (反证:设取第i堆,如果异或和仍为0,那么倒推回去会发现Ai没有变化,即从第i堆取0个,是非法操作)

2、若k≠0

设k的二进制最高位1为第j位,那么我们找到一堆石子Ai,满足Ai的二进制第j位为1,然后Ai->Ai xor k(xor k后,Ai的第j位变成0,又因为高位没变,因此Ai一定变小了,为合法操作)

此时  A1 xor A2 xor … Ai xor k ... xor AN =k xor k =0

综上,如果k=0,要么必败,要么变成k≠0;如果k≠0则一定有一种方案使得k=0

因此根据必胜、必败局面的定义,k=0是必败局面(只能到达必胜局面k≠0);k≠0是必胜局面(能够到达必败局面即k=0)

二、ICG游戏与SG函数

1、引子

给定一个有向无环图和一个起始顶点上的一枚棋子,Alice和Bob交替的将这枚棋子沿有向边进行移动,无法移动者判负。问是否有必胜策略。

2、讨论

事实上,这个游戏可以认为是所有ICG游戏的抽象模型。也就是说,任何一个ICG游戏都可以通过把每个局面看成一个顶点,对每个局面和它的子局面连一条有向边来抽象成这个“有向图游戏”。

下面我们就在有向无环图的顶点上定义SG(Sprague-Garundy)函数。

3、SG函数的建立

首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数。例如mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。

对于一个给定的有向无环图,定义关于图的每个顶点x的SG函数sg如下:sg(x)=mex{ sg(y) | x->y }。也就是说,一个点的SG函数为在它所有后继的SG函数中都未出现的最小的值。

4、SG函数的性质

(1)SG函数与必胜、必败局面

首先,所有的没有出边的顶点(即终止局面),其SG值为0,因为它的后继集合是空集。

然后对于一个sg(x)=0的顶点x,它的所有后继y都满足 sg(y)≠ 0。(如果有一个sg(y)=0则sg(x)≠0)

对于一个sg(x)≠ 0的顶点,必定存在一个后继y满足sg(y)=0。(如果没有sg(y)=0则sg(x)=0)

这个时候你就应该有所发现了!SG函数的性质和N,P局面的性质非常相似!

即:sg(x)=0说明x是必败局面(下一步必定到达必胜局面),否则x是必胜局面(下一步能到达必败局面)

(2)ICG游戏 +SG函数 ⇒ Nim游戏

根据上一个性质,我们通过倒推计算有向无环图的每个顶点的SG值,就可以对每种局面找到必胜策略了。

如果将有向图游戏变复杂一点,比如说,有向图上并不是只有一枚棋子,而是有n枚棋子,每次可以任选一颗进行移动,这时,怎样找到必胜策略呢?

让我们再来考虑一下顶点的SG值的意义:

当sg(x)=k时,表明对于任意一个0<=i<k,都存在x的一个后继y满足sg(y)=i。也就是说,当某枚棋子所在的顶点SG值是k时,我们可以走到0,1,...,k-1的顶点(其实也可能到达>k的顶点),但绝对不能保持k不变。

那么可以根据这个联想到Nim游戏,Nim游戏的规则就是:每次选择一堆数量为k的石子,可以把它变成0、变成1、……、变成k-1,但绝对不能保持k不变。

这表明,如果将n枚棋子所在的顶点的SG值看作n堆相应数量的石子,那么这个Nim游戏的每个必胜策略都对应于原来这n枚棋子的必胜策略!

对于n个棋子,设它们对应的顶点的SG值分别为(a1,a2,...,an),再设局面(a1,a2,...,an)时的Nim游戏的一种必胜策略是把ai变成k,那么原游戏的一种必胜策略就是把第i枚棋子移动到一个SG值为k的顶点。

这听上去有点过于神奇——怎么绕了一圈又回到Nim游戏上了。

其实我们还是只要证明这种多棋子的有向图游戏的局面是P-position当且仅当所有棋子所在的位置的SG函数的异或为0。这个证明与上节的Bouton's Theorem几乎是完全相同的,只需要适当的改几个名词就行了。

(3)必败局面 ⇔ sg的异或值为0

刚才,我为了使问题看上去更容易一些,认为n枚棋子是在一个有向图上移动。但如果不是在一个有向图上,而是每个棋子在一个有向图上,每次可以任选一个棋子(也就是任选一个有向图)进行移动,这样也不会给结论带来任何变化。

所以我们可以定义有向图游戏的和(Sum of Graph Games):设G1、G2、……、Gn是n个有向图游戏,定义游戏G是G1、G2、……、Gn的和(Sum),游戏G的移动规则是:任选一个子游戏Gi并移动上面的棋子。Sprague-Grundy Theorem就是:sg(G)=sg(G1)^sg(G2)^...^sg(Gn)。也就是说,游戏的和的SG函数值是它的所有子游戏的SG函数值的异或。

(那么对于一开始的那个经典Nim问题,从n堆石子A1,A2,...,An中选一个石堆取,可以认为每一堆石子Ai都是一个子游戏Gi,可以发现如果只有一堆石子Ai那么其SG函数为sg(Ai)=Ai,那么n堆石子的总SG函数就是sg(A1) xor sg(A2) xor ... xor sg(An) =A1 xor ... xor An,这和一开始的那个定理是相同的,如果 SG=sg(A1) xor sg(A2) xor ... xor sg(An) =A1 xor ... xor An =0,则当前局面必败)

由于任何一个ICG都可以抽象成一个有向图游戏。所以“SG函数”和“游戏的和”的概念就不是局限于有向图游戏。我们给每个ICG的每个position定义SG值,也可以定义n个ICG的和。所以说当我们面对由n个游戏组合成的一个游戏时,只需对于每个游戏找出求它的每个局面的SG值的方法,就可以把这些SG值全部看成Nim的石子堆,然后依照找Nim的必胜策略的方法来找这个游戏的必胜策略了!

所以,对于我们来说,SG函数与“游戏的和”的概念不是让我们去组合、制造稀奇古怪的游戏,而是把遇到的看上去有些复杂的游戏试图分成若干个子游戏,对于每个比原游戏简化很多的子游戏找出它的SG函数,然后全部异或起来就得到了原游戏的SG函数,就可以解决原游戏了。这种“分而治之”的思想在下一节介绍的“翻硬币游戏”中将被应用得淋漓尽致。还是敬请期待。

posted @ 2022-08-10 16:23  th-is  阅读(121)  评论(0)    收藏  举报