Nim博弈和Sprague-Grundy定理

本文介绍了Nim博弈及其获胜策略,通过异或操作判断先手胜负。接着阐述了Sprague-Grundy定理,利用Minimum Excludant(MEX)求解各状态的Grundy number,确定博弈的最终结果。当nim sum为0时,先手必败。

Nim博弈和Sprague-Grundy定理

一、 Nim博弈

Nim游戏是指有n个堆,每堆有若干石子,现在有两个玩家轮流在堆中去取石子,要求至少取一个石子,至多取一个堆的石子,谁最先将最后的石子取完就赢了。若以[x1,x2,...,xn][x_1,x_2,...,x_n][x1,x2,...,xn]表示每堆石子的个数,则称xk(k∈1,...n)x_k(k\in1,...n)xk(k1,...n)为状态。这种游戏有一个规律,就是所有状态相互异或以后的值若为0,则先手(也就是第一个取石子的人)必输,反之必赢。即 result=(x1)∧(x2)∧...∧(xn)result=(x_{1})^{\wedge}(x_{2})^{\wedge}...^{\wedge}(x_n)result=(x1)(x2)...(xn),如果result=0result=0result=0,则先手必输。

二、 Sprague-Grundy定理

在介绍SGSGSG定理之前,首先介绍一下Minimum ExcludantMinimum\space ExcludantMinimum ExcludantMinimum ExcludantMinimum\space ExcludantMinimum Excludant是指不在集合中的最小非负整数,使用MEX(⋅)MEX(\cdot)MEX()表示。例如,集合S={0,1,3,8}S=\left\{ 0,1,3,8\right\}S={0,1,3,8},则MEX(S)=2MEX(S)=2MEX(S)=2。一个博弈当前状态的Grundy numberGrundy\space numberGrundy numberMEX({g1,g2,...,gn})MEX(\left\{g_1,g_2,...,g_n\right\})MEX({g1,g2,...,gn}),其中g1,g2,...,gng_1,g_2,...,g_ng1,g2,...,gn表示 的是我们可以从当前状态移动到的状态的Grundy numberGrundy\space numberGrundy number。其中MEX({})=0MEX(\left\{\right\})=0MEX({})=0即当一个状态不能移动到下一个状态时,Grundy numberGrundy\space numberGrundy number000。当一个状态的Grundy numberGrundy\space numberGrundy number为0时,表示从当前状态的先手必输,反之必赢。以一个例子为例:
假设一个堆有6个coinscoinscoins,每次可以取1∼31\sim313coinscoinscoins,则Grundy(0)=0,Grundy(1)=MEX(Grundy(0))=MEX(0)=1,Grundy(2)=MEX(Grundy(0),Grundy(1))=MEX(0,1)=2,Grundy(3)=MEX(Grundy(0),Grundy(1),Grundy(2))=MEX({0,1,2})=3,Grundy(4)=MEX(Grundy(3),Grundy(2),Grundy(1))=MEX({3,2,1})=0,Grundy(5)=MEX(Grundy(4),Grundy(3),Grundy(2))=MEX({0,3,2})=1,Grundy(6)=MEX(Grundy(5),Grundy(4),Grundy(3))=MEX({1,0,3})=2Grundy(0)=0,\\ Grundy(1)=MEX(Grundy(0))=MEX(0)=1,\\ Grundy(2)=MEX(Grundy(0),Grundy(1))=MEX(0,1)=2,\\ Grundy(3)=MEX(Grundy(0),Grundy(1),Grundy(2))=MEX(\left\{0,1,2\right\})=3,\\Grundy(4)=MEX(Grundy(3),Grundy(2),Grundy(1))=MEX(\left\{3,2,1\right\})=0,\\Grundy(5) =MEX(Grundy(4),Grundy(3),Grundy(2))=MEX(\left\{0,3,2\right\})=1,\\Grundy(6)=MEX(Grundy(5),Grundy(4),Grundy(3))=MEX(\left\{1,0,3\right\})=2Grundy(0)=0,Grundy(1)=MEX(Grundy(0))=MEX(0)=1,Grundy(2)=MEX(Grundy(0),Grundy(1))=MEX(0,1)=2,Grundy(3)=MEX(Grundy(0),Grundy(1),Grundy(2))=MEX({0,1,2})=3,Grundy(4)=MEX(Grundy(3),Grundy(2),Grundy(1))=MEX({3,2,1})=0,Grundy(5)=MEX(Grundy(4),Grundy(3),Grundy(2))=MEX({0,3,2})=1,Grundy(6)=MEX(Grundy(5),Grundy(4),Grundy(3))=MEX({1,0,3})=2,由于Grundy(6)=2Grundy(6)=2Grundy(6)=2,所以只要先手就必赢,因为先手可以取走2个,这样就到达了状态4,而Grundy(4)=0Grundy(4)=0Grundy(4)=0,轮到对手先手,必输。
上述游戏只有一个堆,如果有多个堆,则一个博弈的Grundy numberGrundy\space numberGrundy number为子博弈的Grundy numberGrundy\space numberGrundy number的异或(即nim sumnim\space sumnim sum)后的值。如果值为0则必输,这个就是sprague grundysprague\space grundysprague grundy定理。

如果将nimnimnim博弈和sprague grundy theoremsprague\space grundy\space theoremsprague grundy theorem联系起来的话,假设有nnn堆石子[x1,x2,...,xn][x_1,x_2,...,x_n][x1,x2,...,xn],如果至少选择一个,至多选择一堆,则Grundy(x1)=MEX(Grundy(0),Grundy(1),...,Grundy(x1−1))=x1Grundy(x_1)=MEX(Grundy(0),Grundy(1),...,Grundy(x_1-1))=x_1Grundy(x1)=MEX(Grundy(0),Grundy(1),...,Grundy(x11))=x1,同理可得Grundy(xn)=xnGrundy(x_n)=x_nGrundy(xn)=xn,因此,nim sumnim\space sumnim sum(x1)∧(x2)∧...∧(xn)(x_1)^{\wedge}(x_2)^{\wedge}...^{\wedge}(x_n)(x1)(x2)...(xn)

Grundy numberGrundy\space numberGrundy number的过程可以用如下代码表示:

   int a[m];//给定的可选择的序列,大小为m;
   int g[maxn];
   //mex运算 找到集合中最小的非负整数
   int mex(set<int>& s)
   {
       int a = 0;
       while(s.count(a))
           a++;
       return a;
   }
   int main()
   {
      g[0] = 0;
      for(int i = 1; i < n; i++)
      {
         set<int> s; // s保存当前状态可以到达的所有其他状态的grundy值
         for(int j = 0; j < m; j++)
         {
             s.insert(g[i - a[j]]);
         }
         g[i] = mex(s); //当前状态的grundy值
      }
   }

求得所有堆的GrundyGrundyGrundy值以后,将所有的值异或,结果为0的话则先手必输。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值