在本人的 POJ 1740 解题报告中,已经提到这是一题有关博弈论的题目。现在,就让我们来一窥博弈论中的无偏博弈及其理论,并应用这些知识来解决几道 POJ 题目。本文定位于无偏博弈的入门介绍和其简单应用,因此,博弈定理的证明和详细讨论将被忽略。
一、什么是无偏博弈?
通俗地说,博弈就是“游戏”,而无偏博弈就是一种任意局势对参与游戏的两个选手来说都是平等的回合制游戏。因此,选手的区别只在于谁先进行第一个回合(即谁是先手)。按此定义,象棋、五子棋等都不是无偏博弈。这是因为,在这些棋类中,对于任意一个局势,有些棋子只能由某一选手移动;例如,在中国象棋中执红的选手在每一回合中只能操作红棋,而不能操作黑棋。
除了局势对选手平等之外,还有额外的三个要求:
(1)信息完全公开。这就是说,有关游戏的所有信息对所有选手都是可知的。因此,像扑克之类的游戏,通常都不是无偏博弈,因为,你看不到对手的牌,对手的也看不到你的。
(2)无随机性。一旦游戏完全设立好,每一人操作都是非随机的。这就排除了大富翁之类的游戏。
(3)有限步终止。游戏在有限步之内必然终止。这是一条很强的要求。例如,象棋之类的游戏就不满足这条要求。比如,当对手下感情棋时,游戏就可能无限进行下去。
说了这么多不是无偏博弈的游戏,现在举一个是的例子,而最经典的例子莫过于最简单的取石子游戏,也叫尼姆(Nim)博弈:有两堆石子,石子数目为 m > 0 和 n > 0。两个选手轮流从这些石堆中取走石子。在每一回合中,选手选定一个至少有一个石子的石堆,从该堆中取走至少一个石子。若某选手最后取走所有的石子,则该选手获胜,游戏宣告结束。
现在我们来验证这是一个无偏博弈。首先,任意局势对选手都是平等的。在任意回合中,如果一个操作或策略(取走x个石子)是被规则允许的(在这里,是 1<= x <= k),则无论该回合是由选手a或选手b进行,该回合的选手都可以采取该操作或策略。其次,信息完全公正。显然,选手采取的任何策略对于对手来说都是可见的。再次,无随机性。这个很显然。最后,有限步终止。因为每一回合中,至少有一个石子被取走,因此,石子的数目一直在减少。这样,最多 m+n 个回合之后,将没有石子留下,游戏结束。
二、有向无环图游戏
现在,设想一个有向无环图上(如无特别说明,本系列中的图都是指有向无环图)的棋子移动游戏:在一个有向无环图上,在某个顶点处有一颗棋子。在每一回合中,选手把该棋子沿某一出边移动到相邻的顶点上。当某选手最后移动棋子,从而使棋子处于一个没有出边的顶点上时,该选手获胜,游戏结束。
之所以介绍这个图上的游戏,是因为,任意一个无偏游戏,等价于一个有向无环图上的棋子游戏:在无偏游戏中,把每一个局势,也即每一个状态,看成是一个有向图上的一个顶点,而把状态间的转移看成一条有向边。由于有限步原则,该图必然是无环图。在图上的对应于游戏最初状态的顶点处放置一颗棋子,采取某个策略把一个状态 x 变成状态 y则相当于把棋子从对应于状态 x 的顶点 u 沿着有向边移动到对应于状态 y 的顶点 v 上。当棋子无法移动时,游戏就结束。由于图没有环,图上的任意路径都是有限长的,因此,棋子在有限步之后必定无法移动,即到达一个没有出边的顶点上。由于这个对应关系,当我们讨论一个无偏游戏时,总同时假定了一个等价的有向无环图上的游戏。因此,我们不再区分状态和顶点这两个概念。
没有出边的顶点称为 P-态。如果一个状态可以转移到某一个 P-态,则称其为 N-态。如果一个状态只能转移到 N-态的顶点上,则也称为 P-态。在某回合中,如果选手面对的是 P-态,则当对手以最优策略进行游戏时,该选手必败。这是因为,如果该状态没有出边,则游戏结束,选手输掉了游戏;否则,无论他的策略是什么,都只能转移到某个N-态上,从而对手可以接着把该棋子转移到某个 P-态上。因此,P-态也叫必败态(相对于先手而言),N-态为必胜态(同样的,相对于先手而言)。
一个很自然的问题是,对于任意一个顶点,是否要么为 P-态,要么为 N-态?对于顶点数有限的图,回答是肯定的。证明留给读者,或者回复本文:)
另外注意,可以存在顶点数无限,甚至不可数的有向无环图游戏,但每一条路径长度却是有限的。例如,考虑如下游戏:两个选手轮流向一个半径为 R 的桌面上摆放半径为 r 的硬币,使得所有的硬币不得有任何部分位于桌面外,且硬币间互不重叠。摆下最后一个硬币的选手获胜。这个游戏中,状态数目是不可数,但路径长度是有限的,最长不过 R2/r2。
图游戏可以扩展到在多个图上同时进行的游戏,即图游戏的和:设想 n 个图 G1,G2,...,Gn,每个图上在某个顶点处放置一颗棋子。在每一回合中,选手选择一个可以移动棋子的图,并且移动该图上的棋子。当某选手进行最后一次移动,从而使得所有的图上,棋子都无法移动,则游戏结束,该选手获胜。这个图游戏用 G=G1 x G2 x ... Gn 表示,并称其为 G1,G2,...,Gn 的和。例如,上述的取石子游戏可以看成是两个图游戏的和,每个子图游戏对应一个石子堆。
三、Nim 和
学计算机的读者对异或运算应当时非常熟悉的:1⊕1=0⊕0=0,1⊕0 = 0⊕1=1。⊕运算满足交换律和结合律。并且有如下性质:
(1)x⊕y=0 当且仅当 x=y
(2)x⊕0=x。
有一道有关异或运算的很有名的题目:给定一个数组,除了某个数只出奇数次之后,其它的数都出现了偶数次,请找出这个数。答案就是对所有数进行异或运算,结果就是所求的数。这正是因为 x⊕x=0,x⊕0=x。
异或运算也被称为Nim 和,这是因为它跟尼姆游戏的密切关系。回到前面提到的取石子游戏。两堆石子数目相等的状态为 P-态。这时因为,无论先手从某堆石子中取走多少石子,对手总是可以在另一堆石子上取走相同数目的石子,从而使得两堆石子的数目再次相等。最终,先手将被逼取走某堆中的所有石子,而对手成为最后一个取走石子的选手,从而获胜。巧的是,在 P-态中,两堆石子数目的异或为 0。不过,这绝对不是巧合而已。事实上,我们可以断言,在有任意数目石堆的取石子游戏中,P-态为那些所有堆的石子数目的异或为 0 的那些状态。即,若一共有 m 堆,每堆有 ck 个石子,则当 c1⊕c2...⊕cm=0 时,状态 (c1,c2,...,cm) 为 P-态。这个结论很美妙,证明也不是很难。实际上,它只是某个更一般的定理的简单推论而已。我们接下来就介绍这个强大的定理。
四、Sprague-Grundy 定理
首先,定义Sprague-Grundy 函数(简称 SG 函数):在一个图游戏中,定义一个顶点到非负整数的函数 SG 如下
SG(u)= 最小不属于整数集合 {SG(v) | v 是 u 的后继(即有一条边从 u 指向 v)}的非负整数。
若用 F(u) 表示顶点 u 的所有后继的集合,即 F(u) = { v | 有一条边从 u 指向 v },用 mex(S) (minimal exclusive) 表示最小的不属于集合 S 的非负整数,则 SG(u) = mex( F(u) )。
例如,在取石子游戏中,假定只有一堆石子,石子数目为 n。则 F(k)=k,0<=k<=n。特别的 F(n)=n。简单的思考可以证明,状态为 P-态当且仅当其 SG 值为0,为 N-态当且仅当 SG 值大于0。
著名的Sprague-Grundy 定理断言,对于有限图游戏 G=G1 x G2 x ... x Gn 上的顶点 (u1,u2,...,un), 其 SG 值为其子图游戏各顶点的 SG 值之 Nim 和,即 SG(u1,u2,...,un)=SG(u1)⊕SG(u2)⊕...⊕SG(un)。证明不难,从略。
有了这个定理,通过把游戏分解成多个图游戏的和,就可以把复杂的 P-态 判定问题转换成南计算简单子图游戏的 SG 值和子图间顶点 SG 值的 Nim 和,从而使很多游戏的分析变得简单起来。例如,考虑有 n 个堆的取石子游戏。每个堆可以看成一个图游戏,n 个堆上的取石子游戏就成了这些子图游戏的和。则状态 (c1,c2,...,cn) 的 SG 值为 SG(c1)⊕SG(c2)⊕...⊕SG(cn)=c1⊕c2⊕...⊕cn。这也验证了第三节中的断言。
SG 函数的计算并不难,应用深度优先搜索即可。
// procedure to compute SG value for vertex u function SG(u) set F to be empty set for each v who is a follower of u do add SG(v) to the set F end for return mex(F) end function
在实际的代码实现中,计算好的 SG 通常被记录起来,从而避免重复运算。
基础的无偏博弈就先介绍到这里。对此问题感兴趣的读者,包括定理的证明,本人推荐 UCLA 的 Ferguson 教授写的一篇讲稿(点击这里)。这篇讲稿通俗易懂,还带有练习,是不错的无偏博弈入门读物。
五、应用
现在就让我们用这个强大的武器来解决一些原先看起来很难现在很水的 POJ 题目。
(1)POJ 2234 (Matches Game)。这个就是有多个堆的取石子游戏。直接应用定理即可。
(2)POJ 2425 (A Chess Game)。这个也是定理的直接应用,只不过这次是直接应用于有向图上而已。计算出每个图的初态的 SG 值,然后取 Nim 和即可判断是否为 P-态。
(3)POJ 2960 (S-Nim)。这个是更一般的取石子游戏。每次取的石子的可能数目被限定于几个整数,而不是任意整数。解题思路和 (2) 相同,都是要求每个堆上的初态的 SG 值。
(4)POJ 1704 (Goergia and Bob)。这题也是一个无偏博弈,可以直接通过建立相应的图来求 SG 值。不过,这样一来,这个图会很大,计算量也不少。更好的做法是把游戏分解成多个游戏,使得每个子游戏的 SG 值能够容易计算出,最后应用定理求出原来图的初态的 SG 值,从而判断是否为 P-态。那么,最关键的就是如何分解游戏了。观察到一个棋子是否可以移动取决于它左边相邻的棋子,我们可以从最右边开始,把两个相邻的棋子分成一组,若棋子的有奇数个,则在棋盘的最左边设置一个虚拟的棋子。这样,每组棋子看成一个单独的游戏,其终态就是两个棋子紧挨在一起。从这个角度看,每个子游戏就是一个石堆,于是,每个子游戏就是一个取石子游戏,石子的数目等于两颗棋子之间的空格数目;而总的游戏就是有多个堆的取石子游戏。
(5)POJ 2348 (Euclid's Game)。这个是著名的经典 Euclid 游戏的一个变体。把每个状态看成图上的顶点,可以发现,如果顶点的出度至少为2,更从该状态出发,可以存在一条长度为奇数的路径到达终态或另一个出度至少也为2的顶点,并且这条路径上的顶点,除了端点外,出度都为1。因此,出度至少为2的顶点都是 N-态。出度为0的显然是终态。出度为1的顶点,如果它到最近的N-态的路径长度为偶数,则为 N-态;否则为 P-态。这样,问题就解决了。不过,这个问题存在更简单的解决办法。它 P-态和经典的 Euclid 游戏的 P-态存在极其简单的关系:经典的 Euclid 游戏中的 P-态,除了两数相等这一情况外,都是本题游戏中的 P-态。而经典的 Euclid 游戏中的 SG 函数,存在简单的解析解,这个解和黄金分割有关。详细见 《The Sprague-Grundy function of the game Euclid》(Nivasch - 2004)一文。
(6)POJ 2975 (Nim)。这道题也是一道经典的多堆取石子游戏。和题 2234 所不同的是,它不是要判定某个状态是 P-态还是 N-态,而要求获胜策略的数量。设初始状态的 SG 值为 s,则 s 的 MSB (most significant bit) 是指 s 的二进制表示中最左边的非0位。设 s 的 MSB是 x。可以证明,获胜策略的数量是所有堆的 SG 值中,第 x 位非 0 的 SG 值的个数。
(7)POJ 1082 (Calendar Game)。这题也可以用 SG 函数来分析,不过存在更简单的解决办法。注意到一般情况下,移动一天,或移动一个月,都将改变月或日的奇偶性,例外的情况发生在每个月的最后一天。现在先假定这些例外的日期不能被移动到。由于目标日期 11 月 4 日 是奇数月,偶数日,即奇偶不同,如果一个状态是奇奇或偶偶的情况,选手总可以移动一天或一个月转移到奇偶或偶奇(统称为奇偶)的状态上。而处于奇偶状态时,只能移动到奇奇或偶偶的日期上,从而永远也不可能到达终态。因此,奇偶为 P-态,奇奇或偶偶为 N-态。现在考虑例外的边界情况。逐个仔细研究可以发现,只有 9.30 和 11.30是两个例外。这两个奇偶的状态竟然也可以转到奇偶的状态上!因此,他们也是 N-态。至此,问题解决。
(8)POJ 1067 (取石子)。经典 Wythoff 博弈,通解和黄金分割有关。
(9)... ...