浅谈算法——博弈论

网上的博弈博客和论文有很多,但是有些没有详细的证明,仅仅是给出了结论。今天作者将一些常见的博弈论模板集中起来,给大家介绍一下博弈论中一些单一游戏的决策和常见的Nim模板与证明。

注:下列游戏都建立在双方都有最优策略的情况下,若未加以说明,则每人每次至少取一个石子。

例1:取石子游戏之一

有两个游戏者:\(A\)\(B\),有\(n\)颗石子。

约定:两人轮流取走石子,每次可取\(1,2\)\(3\)颗。\(A\)先取,取走最后一颗石子的人获胜。

问题:\(A\)有没有必胜的策略?

分析:这是小学必备奥数题之一,我们可以很容易的知道,当\(n\)\(0,4,8,12……\)时,\(A\)必定会输,因为不论\(A\)取多少,\(B\)只要和\(A\)共同取走\(4\)即可;当\(n\)不为\(0,4,8,12……\)时,\(A\)只需要将\(n\)取成\(4\)的倍数,这样就变成了\(B\)先取,\(B\)一定会输,所以\(A\)一定会赢。

经过我们的分析发现,对这个游戏而言,\(0,4,8,12……\)这些状态是对于先手的必败状态,而其他状态是对于先手的必胜状态

如果我们推广一下,每次不一定取\(1,2,3\)颗,而是取\(1\sim m\)颗,那么我们就可以得到,如果\(n\%(m+1)=0\),即为先手必败状态,否则为先手必胜状态。而这个游戏就是著名的巴什博弈(Bash Game)

下面,我们现在介绍一下有关博弈的一些名词和概念

1、平等组合游戏

  • 两人游戏。
  • 两人轮流走步。
  • 有一个状态集,而且通常是有限的。
  • 有一个终止状态,到达终止状态后游戏结束。
  • 游戏可以在有限的步数内结束。
  • 规定好了哪些状态转移是合法的。
  • 所有规定对于两人是一样的。

因此我们的例1提到的游戏即为一个平等组合游戏,但是我们生活中常见的棋类游戏,如象棋、围棋等,均不属于平等组合游戏,因为双方可以移动的棋子不同,不满足最后一个条件;而我们后续提到的游戏,以及博弈中的其他游戏,基本属于平等组合游戏

2、N状态(必胜状态),P状态(必败状态)

像例1的分析一样,\(0,4,8,12……\)等状态就是对于先手的P状态(必败状态),其他的则是对于先手的N状态(必胜状态)。

那么我们定义两个状态之间的转换:

  • 所有的终止状态都为P状态
  • 对于任意的N状态,存在至少一条路径可以转移到P状态
  • 对于任意的P状态,只能转移到N状态

证明过于简单,这里不再赘述,我们只需要明白一点,每个人都会选择最策略即可。

当然这里所说的都是最后走步的人获胜的游戏,至于那些走到最后失败的游戏,我们在最后做了一个简单的讲解(Anti Nim)。

例2:取石子游戏之二

将例1的游戏扩展一下,我们定义一个集合\(S=\{{p_{1},p_{2},...,p_{k}}\}(k \in Z^*)\)\(A,B\)在游戏的时候取走的石子数必须是集合里的数,其他条件不变。

那么,\(A\)还有必胜策略吗?

有没有必胜策略,我们关键是要找到哪些状态是P状态,哪些状态是N状态,不过,本题没有例1那么容易判断,因此我们需要引入一个新东西——SG函数,它的定义如下:

\[f(v)=mex\{f(u)|u\in child[v]\}\]

其中,mex(minimal excludant)是定义在整数集合上的操作。它的自变量是任意整数集合,函数值是不属于该集合的最小自然数。

\[mex(A)=min\{k|k \in \complement_{N}A\}\]

那么,终止状态的SG值显然为\(0\),并且SG值为\(0\)的状态就是P状态,SG值不为\(0\)的状态就是N状态。
证明则非常显然,SG值为\(0\)的状态,说明它的所有后继状态都不为\(0\),也就是它只能转移到非\(0\)状态,而SG值不为\(0\)的状态则不一样。那么SG值为\(0\)的状态就是必败状态的定义,SG值不为\(0\)的状态就是必胜状态的定义,所以我们只需要用集合S求出每个状态的SG值即可。

类似代码请见[POJ2960]S-Nim

例3:取石子游戏之三

\(n\)个石子,\(A,B\)两人轮流取石子,规定他们每次至多只能取当前石子总数\(\lceil \dfrac{s}{2}\rceil\)个石子,问\(A\)先手是否有必胜策略

这题主要是为了加强大家对SG函数的理解,我们考虑从\(0\)开始

\(SG(0)=0,SG(1)=1,SG(2)=0,SG(3)=mex\{SG(3-1),SG(3-2)\}=2\)
\(SG(4)=mex\{SG(4-1),SG(4-2)\}=1...\)

我们把他们列出来找下规律:

0,1
0,2,1,3
0,4,2,5,1,6,3,7
0,8,4,9,2,10...

好像有个很奇怪的规律:数列在间隔递增,上一行的数间隔着插在下一行的数中间。没错,这就是本题SG函数的规律,先手必败当且仅当SG值为\(0\)

例4:取石子游戏之四(Nim游戏)

\(n\)堆石子,石子数目分别为\(x_{1},x_{2},...,x_{n}\)\(A,B\)两人每次可以选一堆石子取走任意多个,问\(A\)先手是否有必胜策略。

这题相当于例2的扩展版本,由于这里有多堆石子,因此我们可以得到多个SG值,而且这些SG值必定为\(x_{1},x_{2},...,x_{n}\),那么我们怎么由这一些SG值得到整局游戏的SG值呢?

Nim游戏的神奇之处在于它的SG值和异或扯上了关系,Nim游戏中先手必败当且仅当\(x_{1}\oplus x_{2}\oplus...\oplus x_{n}=0\),\((\oplus\)为异或),那么,这个为什么是成立的?

首先,\(\oplus\)满足如下定律和性质

  • 交换律:\(x\oplus y=y\oplus x\)
  • 结合律:\(x\oplus(y\oplus z)=(x\oplus y)\oplus z\)
  • 拥有单位元:\(0\oplus x=x\)
  • 相同两数运算为0:\(x\oplus x=0\)
  • 消除律:\(x\oplus y=x\oplus z\Rightarrow y=z\)

当Nim游戏的SG值为\(0\)时,我们假定取\(x_{k}\)中的某些石子,使得其变成\(x_{k}'\),我们假设\(x_{1}\oplus x_{2}\oplus...\oplus x_{k}\oplus...\oplus x_{n}=0=x_{1}\oplus x_{2}\oplus...\oplus x_{k}'\oplus...\oplus x_{n}\),根据消除律可得,\(x_{k}=x_{k}'\),这与我们的条件相矛盾,因此说明在取了石子之后,SG必然发生了改变;

那么对于一个SG值不为\(0\)的状态,我们必然可以通过一个操作,使得SG值变\(0\)。我们只需要找到当前SG最左端为\(1\)的一列(二进制),任意找到一堆石子使得那一列同样为\(1\),从这堆中取走若干个石子,使得SG'值为\(0\)。这是显然可以的,因为将那一列变成\(0\),这个数就必然变小了,对于其他列只需要把\(0\)变成\(1\)\(1\)变成\(0\)即可。

因此,我们得到,对于Nim游戏而言,必败状态当且仅当\(x_{1}\oplus x_{2}\oplus...\oplus x_{n}=0\),对于其他情况,先手必能使当前局面变成必败状态。

代码请见[POJ2975]Nim

例5:取石子游戏之五(Nimk)

\(n\)堆石子,石子数目分别为\(x_i\)\(A,B\)两人每次可以选取最多\(k\)堆石子,并从选中的每堆石子堆中取走任意多的石子,问\(A\)是否有必胜策略

首先这题又称Nimk,那么肯定和Nim游戏有关联,其实Nimk就是Nim游戏的一个简单扩展

Nimk存在必胜策略,当且仅当,将所有石子数转成二进制后,存在某位上,所有二进制数中1的个数之和\(\%(k+1)\)不为\(0\),用数学语言表述,则存在一个数\(t\),使得\((\sum\limits_{i=1}^n x_i\land2^{t-1})\%(k+1)\ne 0\)

如何证明?首先终止局面全为\(0\),满足必败条件

对于任意一种必胜状态,必然存在一种取石子方式,使得其可以转移到必败状态。我们设必胜状态下,\(1\)的个数\(\%(k+1)\)不为\(0\)的最高二进制位上有\(m\)\(1\),则将这些\(1\)都改成\(0\)需要更改\(m\)堆;若遇到下一个二进制位上,\(1\)的个数\(\%(k+1)\)不为\(0\),记该位上有\(r\)\(1\),并且记之前改变的\(m\)堆在该位上有\(a\)\(1\)\(b\)\(0\)(所有变量都是在\(\%(k+1)\)之后的值)

然后我们分情况讨论:

  • \(a\geqslant r\),则将\(r\)\(1\rightarrow0\)
  • \(b\geqslant k+1-r\),则将\(k+1-r\)\(0\rightarrow 1\)
  • \(a<r\)\(b<k+1-r\),则我们改变之前\(m\)堆以外的\(r-a\)堆,那么此时我们改变的堆数为\(m+r-a\Rightarrow a+b+r-a\Rightarrow b+r\),又因为\(b+r<k+1-r+r\Rightarrow k+1\),所以我们改变的堆数\(m-r+a<k+1\),那么这样的改法是合法的

重复上述操作,我们必然能使每一位上的\(1\)的个数\(\%(k+1)\)\(0\),即转移到先手必败态

那么对于任意一个先手必败态而言,由于我们每次最多只能选取\(k\)堆,所以我们不能在同一二进制位上改变\(k+1\)个值;而且每次改变会导致一系列的连锁反应,因此我们无法从一个先手必败态转移到先手必败态,证毕

其实Nim游戏相当于Nimk中\(k=1\)的情况……

例6:取石子游戏之六(Wythoff's Game)

有两堆石子,个数为\(x_{1},x_{2}\)\(A,B\)轮流取石子,规定要么只取一堆的任意多个,要么在两堆里取同样任意多个,问\(A\)先手是否有必胜策略。

这种情况下是颇为复杂的,普通SG函数已经无法解决这个问题。我们用\((a_{k},b_{k}),(a_{k} \leqslant b_{k},k \in [0,n])\)表示两堆物品的数量并称其为局势,如果甲面对\((0,0)\),那么甲已经输了,这种局势我们称为奇异局势。

那么,我们该如何去找到这些奇异局势呢?

首先我们知道,局势\((x,y)\)和局势\((y,x)\)是等价的。考虑递推的思想,我们已经知道\((0,0)\)是个奇异局势,也就是个先手必败态,那么根据定义,能够到达\((0,0)\)状态都为先手必胜态,也就不是奇异局势。

我们从直角坐标系来考虑,\((0,0)\)为奇异局势后,那么\((0,k),(k,0),(k,k)\)都是非奇异状态,我们把它们划去,然后找到第一个没有被划的点,也就是\((1,2)\)\((2,1)\)(因为他俩对称),然后按同样的方法处理,之后找到\((3,5)\)\((5,3)\)...

这样我们可以得到前几个奇异局势是:\((0,0)\)\((1,2)\)\((3,5)\)\((4,7)\)\((6,10)\)\((8,13)\)\((9,15)\)\((11,18)\)\((12,20)\)...

通过找规律,我们大胆猜测一下\((a_{k},b_{k})\)满足:

  • \(a_{k}\)是未在之前出现过的最小自然数

  • \(b_{k}=a_{k}+k\)

下面我们给出其证明:

  • 根据我们寻找奇异局势的方法,可以得知\(a_{k}\)为之前未出现的最小自然数

  • 我们使用数学归纳法,假定之前的\(k\in[1,n],(a_{k},a_{k}+k)\)都为奇异局势,我们只需要证明\((a_{n+1},a_{n+1}+n+1)\)为奇异局势即可

    从局势\((a_{n+1},a_{n+1}+n+1)\)出发,只可能走向三种状态,从左边拿一点,从右边拿一点,或者两边一起拿一点:

    情况一:因为比\(a_{n+1}\)小的数在之前都出现过