【组合游戏与相关的概念】
1.组合游戏
游戏是一个常见的概念,通常它是指娱乐性质的游戏。不过它也可以有一些其它的内涵比如竞争、寻找最优,像商业竞争、外交谈判就是这样的意义下的游戏,尽管不那么有趣、不过战争也可以算作是游戏。
在OI中有许多题目从游戏中提出问题。Alice &Bob 就因此出了名。在这些游戏中组合游戏占了很大一部分,组合游戏其实对我们来说并不陌生,它是是满足这样一些条件的游戏:
1) 游戏有2名参与者。
2) 游戏过程中任意时刻有确定的状态。
3) 参与者操作时可以的操作时将游戏从当前状态改变为另一状态,规则规定了在任意一状态时,可以到达的状态集合。
4) 参与者轮流进行操作。
5) 在游戏出于某状态,当前参与者不能进行操作时,游戏结束。此时参照规则决定胜负。
6) 无论参与者做出怎样的操作游戏在有限部数之内结束(没有平局)。
7) 参与者拥有游戏本身,和游戏过程的所有信息,比如规则、以前自己和对手的操作。
组合游戏还有一个公平性的限制、即2名参与者的操作规则
是相同的。
组合游戏也可以用一个有向图来表示 G=(X,F)X为游戏的状态集合F(X)为X可以到达的状态集合,而结束状态均宣布当前参与者失败。
如果原游戏的结束状态为胜利,那么有必要将图改一下适应题目规则。
组合游戏必然是一个无环图(无平局)。
2.必胜、必败状态
在组合游戏中必胜状态定义为当前玩家有策略能使无论对手做什么操作也可以保证自己胜利的状态。相反,如果之前操作的玩家能够保证胜利、则它是必败的状态
在组合游戏中一个状态如果不是必败状态就是必胜状态,这是显而易见的。通常我们分析做和游戏的目的就是判断一个状态为必胜还是必败,如果必胜,则找出必胜策略。完成这一点仅凭以上定义是不够的,而以下的性质(可以用来判定一组划分是否为必败状态与必胜状态的划分)则明确的指出了一种递推的方法。
1) 结束状态的性质由规则决定。
2) 一个非结束状态,如果它能到达任何必败状态,那么它是必胜状态,否则它就是必败状态。
尽管这对每个组合游戏都适用,但它可不是万能的,有时一个游戏的状
态非常多,计算机无法处理,这时你就得借用别的方法了。
3.Sprague-Grundy 函数
它是定义在组合游戏状态上的函数,用g (X)表示X状态的函数值。它的定如下:
g (X)= min{n| n∈N ,n≠ for y∈F(x)}
形象的说就是X的函数值为与X所能到达的任意点函数值不同的最小自然数。
我想细心的读者已经发现g (X)=0当且仅当X为必败状态,这用其定义很容易验证:
1) 当X为结束状态时,由于g (X)=0它是必败状态。
2) 当X不是结束状态时,如果它能到达必败状态,那么g (X)>0,X是必胜状态。
3) 如果X不是结束状态且它到达的所有状态未必败状态,那么g (X)=0它是必败状态。
这个冗长的定义,看上去毫无意义,因为直接判断一个状态的性质比使
用这个函数要方便多了。但实际上与感觉的相反,这确是许多方法的基石,他的一些性质,使我们分析组合游戏的重要工具。
【概述】
本文介绍的三种基本手段分别是分解游戏,归纳,转化游戏。
【分解游戏】
一、 分解游戏与游戏的和
游戏的和是指这样的游戏:两名参与者轮流操作若干子游戏,每次操作可以选择任意一个子游戏进行操作,最后后操作者胜利。
nim游戏就是这样的典型。
nim游戏为两人轮流从若干堆石子中取走石子,每次可以取走任意一堆中任意数目的棋子,但必须取走至少一枚,取走最后一枚石子的人胜利。它是由若干个一堆石子的特殊nim组成的,每次操作都只能按照子游戏的规则操作一个子游戏。
我们用G=(X ,F)表示G1+ G2+ … … Gn.其中Gi=(Xi ,Fi)是一个简单的组合游戏。则
X=X1 * X2 * X3 *……Xn
对于X= (X1,X2,X3……Xn)
F(X)= F(X1,X2,X3……Xn)=
F1(X1) *{X2}*{X3}* … …{Xn}∪
{X1}* F2(X2) *{X3}* … …{Xn}∪
… …
{X1}*{X2}*{X3}* … … F3(Xn)
二、 Sprague-Grundy 定理
游戏的和往往比它的子游戏复杂许多。比如nim,它的子游戏相当简单:除了没有石子的情况为必败,其他的都是必胜的状态。令X表示有X个石子的状态。但是多堆的情况不仅状态数陡增,而且关系更为复杂使它很难分析。
我们知道一个状态位必败状态当且仅当它的SG函数值为0,所有状态的SG函数值可以完成必胜、必败状态的划分。Sprague-Grundy定理就是用来寻找这样游戏的SG值的。
作为经典游戏nim的规律其实非常简单。对于每一堆石子n堆石子,第i(1<=i<=n)堆石子的个数是Xi,该状态为必败状态当且仅当X1XOR X2XOR……Xn=0。这些状态因为是必败状态,所以SG值也为0
看到这里其实定理的内容很容易猜到了。
Sprague-Grundy Theorem:
对于G=G1+G2+ … … Gn
G(X1,X2,… …Xn) =G1(X1)XORG2(X2)… …Gn(Xn)
证明:
XOR运算有一些重要的运算性质与加法相似,这里做一下必要的介绍(用符号xor表示):
a xor b=c,c的2二进制形式的第i位是a,b二进制形式该位置上的值队2取余的结果。 xor 的运算率有结合率,交换率。除此以外,若a xor b=c则a xor d=c当且仅当b=c;a xor a = 0;a xor 0 = a;
令b=G1(X1) xor … … Gn(Xn),则只需证明:
1) 于任意a∈ N且a < b , 一定存在X’∈ F(X)使G(X’) = a 。
2) 对于任意X’∈ F(X) ,那么有G(X’) ≠ b。
证明1):
令d=a xor b,令d的2二进制位数为k。必然存在i使Gi(Xi)的二进制第k位为1。显然Gi(Xi) xor d < Gi (Xi) ,因此存在X i’∈ Fi(Xi) 使Gi(Xi’) =Gi(Xi) xor d。
b*d = a => a = G1 (X1) xor … …Gi(Xi) xor d … …Gn(Xn)= G(X1… … Xi’,… …,Xn)
因为 (X1… …Xi'… …Xn)∈F(X) 。所以 1) 得证。
证明2):
假设2)不成立,即对于一个任意的X存在X'∈F(X)使G(X')=b。那么令X’=(X1,… …,Xi’,… …,Xn),G(X’)=G1(X1) xor … …Gi(Xi’)… …Gn(Xn)=b。因此Gi(Xi’)=Gi(Xi)与SG函数的定义矛盾,2)得证。
由于在证明中用到了自身,因此需要用数学归纳法。
所以并不是所有的时候SG函数都比必败状态难求吧。将一个游戏分解,就是将它看作数个游戏的和,利用对每一个单独游戏分析的结果来研究整个游戏。几乎所有的子游戏都比游戏的和要简单,因此在面对大多数复杂的游戏之和时,用分解的方法,所有问题都能迎刃而解。
用分解的方法来分析组合游戏
例题1:
ACM ICPC 2006 Asia Regional Contest,Beijing
A Funny Stone Game
David 玩一个石子游戏。游戏中,有n堆石子,被编号为0..n-1。两名玩家轮流取石子。每一轮游戏,每名玩家选取3堆石子i,j,k(i
请编程帮助David。
石子堆的个数不会超过23,每一堆石子不超过1000个。
输入:
输入包含多组数据,每组数据由2行构成,第一行为一个整数n,第二行包含n个整数S0..Sn-1表示每一堆石子的个数。输入以包含一个0的一行结束。
输出:
每组数据的输出依次各占一行。输出格式为“Game t: i j k”,t为数据的序号,i,j,k表示一个保证David能获胜的开局。如果有多种方案,输出字典顺序最小的一组,如果没有这样的方案,i、j、k、均为-1。
分析:
这个游戏用另一种角度来看,可以将每一颗石子看作是一堆石子,如果它是第p堆中的石子,把么它所代表的这堆石子的个数为n-1-p。从而,操作变为拿走一个非0的石堆,并放入2个规模小于他的石堆(可以为0)。这便成了另一个游戏。之所以这么做是因为,转化后的游戏与经典的take&break游戏很相似。
因为石子堆是互不干扰的,因此这个游戏可以看作由若干个只有一堆石子的游戏组成。
先分析子游戏。求子游戏某状态x的SG函数值,我们需要它后继状态的SG函数值,子游戏的后继状态大多数为含有2堆石子的状态,不过2堆均小于x石子数。在了解石子数小于x的状态函数值的条件下,用SG定理可以求得任意后继状态的函数值。
用(p)表示只剩一堆规模为p的石子的状态,(p,q)表示剩下2堆石子,规模分别为p,q的状态。g (i,j) = g (i) xor g (j) ; g(i) = min{n∈ N | n ≠ g (p,q) for n ≥ p≥ 0且 n ≥ q ≥ 0}。
应用以上结论,我们可以递推求得子游戏任意状态的SG函数值。用SG定理可以求得和游戏的任意状态的SG函数值。SG=0,David可以保证他的胜利,否则就不行。至于策略,只要操作之后留下的状态SG值为0就行了。
时间复杂度分析:
以上算法包含O (n)个SG值的计算,计算每一个的时间最多为O(n2),判断必胜状态需要O ( ∑Si ),寻找最优策略需要O (n3)的时间,综上,该算法的时间复杂度为O(n3+∑Si)。
【归纳】
归纳也是分析组合游戏的一种常见方法。通过归纳,我们可以在很短的时间内完成对许多状态的分析。例如对于nim游戏的1堆情形,我们在递推的简单基础上,我们可以归纳得出规模为x的状态,其SG函数值为x,x必败当且仅当x=0。由于归纳结果往往简单得出人意料,所以我想读者们在自己分析组合游戏的时候一定会自然而然地用上这种方法。
归纳的对象除了我们常见的必败状态还可以是刚刚介绍的SG函数。
通常我们做出归纳的基础都是游戏中的简单情形的特点。不过,游戏中简单的情形给予我们的启示是有限的。有时,我们需要在经验而不是事实的基础上做出猜想。许多游戏与经典游戏有着种种相似而又不完全相同,找出其模型上的相似之处,进行合理的猜想有时比从原始数据上进行归纳更直接有效。
例题2:
staircase nim 经典组合游戏
游戏开始时有许多硬币任意分布在楼梯上,共n阶楼梯从地面由下向上编号为0到n。游戏者在每次操作时可以将楼梯j(1<=j<=n)上的任意多但至少一个硬币移动到楼梯j-1上。游戏者轮流操作,将最后一枚硬币移至地上的人获胜。
分析:
这个问题与nim游戏的区别在于移走的硬币不是被扔掉而是被放进了另一堆硬币之中,考虑能否将这一部分楼梯排除考虑范围。奇数号楼梯只能将硬币扔到偶数号楼梯之中,同样偶数号楼梯上的硬币也只会被扔上奇数号楼梯。只考虑奇数号楼梯nim,若偶数楼梯只作容器,那么游戏变为nim。当偶数号楼梯上的硬币可以将硬币移出时,我们是不是仍然可以用nim的方法判断必败状态?
将奇数台阶的硬币数nim和为0称作条件A,结束状态满足条件A;任何满足条件A的状态都到达满足条件A的状态;任何不满足条件A的状态都可以到达满足条件A的状态(nim)。因此一个状态为必败状态当且仅当它满足条件A。
例题3
翻转硬币(经典组合游戏)
在一条直线上排列着一行硬币,有的正面朝上、有的背面朝上。2名游戏者轮流对硬币进行翻转。翻转时,先选一枚正面朝上的硬币翻转,然后,如果愿意,可以从这枚硬币的左边选取一枚硬币翻转。最后翻转使所有硬币反面朝上的玩家胜利。
例如图1所示的状态,将2和12同时翻转就构成一个合法的操作。
分析:
基于转化的思想,如果将位置i上的H看作一堆规模为i的石子,我们就能看到游戏与nim的相似点。不过有许多nim中的合法操作在这个游戏中是无法实现的,比如图一状态中,我们就无法从一堆规模为10的石子中取出其中的5个。不过我们将10与5同时翻转,所得到的状态。对应的nim状态SG值与从10中取5是相同的。因此我们猜想这个游戏的状态SG函数值与对应的nim相同。由于事实上虽然这个游戏无法实现nim的所有操作,但它的状态所能到达的状态SG函数值集合与对应的nim游戏状态相同。因此,它的状态SG函数值与对应nim相同。
【转化游戏】
现实中有许多游戏在一定的形式的掩饰下,隐藏了许多我们分析所必要的特点,有的游戏状态本身包含多种元素和关系异常复杂。面对这些令我们无法下手的情况时,我们应该想到对游戏的转化。
本文介绍2种方法,一是转化游戏的形式(等价转化),而是对状态进行一定条件下的不等价转化。
一、等价转化
同一个组合游戏往往有不同表现形式,比如例题一中所提到的take &break游戏就可以转换成形式截然不同的石子游戏(只要将例题一稍加改变就能与take &break 游戏等价)。
同一个游戏,从不同的角度,我们能够观察到的性质也不同。比如例1在原型下很难体现其游戏的和的本质,经过巧妙的转化后这一性质就浮出水面了。
例题4 :
POI2003/2004 stage I
Game
该游戏在m*1的平板上进行。平板的一些单位格上放有一枚硬币。两名游戏者轮流移动硬币。移动时,选取一枚硬币,将它放在右边最近的空格里,如果不存在,则将它扔掉,扔掉最后一枚硬币的人获胜
在图一表示的状态下,当前玩家可以将2的硬币移动到4,3到4,6到7。
对于给出的状态输出先行者能保证胜利的第一步策略数。
输入
第一行输入m,n 。m如题是般的大小,n为硬币的数量。第二行n个数分别表示每一枚硬币所在的位置。
输出
进一行,保证先行者胜利的策略数。
分析:
首先每一枚硬币都相互影响,因此很难将其看作任何子游戏的和。状态繁多、关系复杂很难直接找到他的必败状态。考虑转换该游戏,经过多次尝试后可以这样转化一下,将任意空格与其左边最近的空格之间的空间看作一阶楼梯,最后一个空格的右边看作一个地面,每段空间中的硬币数为楼梯数那么这个游戏就与staircase nim游戏完全等价了。
小结:
如果,我们不能将例二成功转化,那么对它的分析过程可以让人非常沮丧。面对组合游戏,从不同的角度来观察(转化)它应该作为我们的基本手段之一。我们最熟悉取石子/硬币这类游戏,它可以作为我们的首选。无论怎样转化,我们都要实现对游戏本质和特点的挖掘。
二、不等价的转化
我们分析组合游戏,只需要SG函数值就可以完成,将游戏原汁原味地转化,保持游戏本质不变是不是有些浪费呢?
由于,只需要SG函数值,我们可以期望在保证状态SG函数值不变时,将复杂状态化进行不等价的转化,化简到最朴素的状态,最后轻松解决。
例题5
IPSC 2003 Got Root?
Alice & Bob有一天发现了一株奇怪的灌木、他的枝分叉之后又可以汇合、更奇特的是来自不同的不仅是同一点的分叉可以汇合、即使分叉点相差很远、两根枝条仍然可以生长到一起(组织连在一块儿了)。在我们看来他可以抽象为一个无向图。其中有唯一结点是根。
他们认为这是用来玩游戏的绝佳材料。于是他们打算在这棵树上玩伐木游戏,规则如下:
1.两人轮流从灌木上截下枝条(图上的边),每截下一根枝条就将与根不再相连的部分去掉。
2.截去最后一根枝条的人获胜
Alice 先手。
对于给出的无向图输出输出胜利的人的名字。
分析:
既然要转化、那么我们就要有一个目标,一个更简单的状态。我们先考虑树的情形是否会更简单。经过初步分析以后树形的状态也难以得到直接的结论、它还需要进一步的简化。那么再来考虑图构成一条长链的情况。这时,终于有了令人满意的结果,问题变为了典型的单堆nim,可以直接求得SG函数值。
那么怎样将图转化成链呢?我们分两步进行,先把图转化成树,在将树转化成链,整个过程保持状态的SG函数值不变。
先做第二步,在只有一个分叉点时,这是一个简单的nim,可以转化为一个长为每根单链异或运算结果的单链。在更复杂一些的树上,猜想从末端开始进行这样的操作,将分叉的地方合并成一条链,长度为每条链的异或运算结果,不会改变整个状态的SG值。
这种合并方式可以推广为更一般的结论:对于任意2棵树H1,H2如果他们玩伐木游戏的SG值相同,则将他们接到两个相同图的对应点后,产生的新图SG值是一样的。
它的证明对于证明2个状态的SG函数值相通这样的命题具有一般性,令产生的2个图为G1,和G2。先证明G1+G2后行者有必胜策略:player1截下的是不是H1或H2的边,player2截下相同的边;如果player1截下的是H1或H2的边,则player2截下H1、H2中SG值较高一个的某一边让SG相同。因此g(G1+G2)=0即g(G1)=g(G2)。
接下来要将图转化成树。
图与树的区别在于图有环而树没有,把图转化成树最朴素的思想就是将图中的环一次缩成单个的点,那么相关的边怎么处理?图中的边是游戏操作的对象,我们最好将它们全都留下来,至于端点,如果已经被合并,那么边就变成一个到自己的环。
我们希望这样的转化,可以保持状态的SG函数值。这个结论证明比较长,这里就不再证明,只附在附录中。
不过,这样操作最终会留下大量的self-loop,不难发现,一个self-loop,和一条长为1的单链是等价的,这样,图到树的转化,我们就有了理论依据。
算法:
有了以上的结论,我们可以设计算法将图在SG值不变的条件下转化成一条单链。我们知道,在无向图中,有这样一个划分,每一个集合内删除任意一条边都能保持连通,集合之间则存在桥。每一个集合,可以通过缩环的操作收缩成一个点与成堆的自己到自己的边。我们的算法可以将图用O(e)的时间对图进行这样的收缩,再用O(n)的时间完成到树和链的转化,整个过程保持状态SG函数值不变。完成转化后,问题就很容易解决了。
该算法时间复杂度为O(e)。