博弈论入门(Nim、sg定理)
通常由以下形式构成:给定一个游戏规则,甲、乙轮流出手行动,最后无法行动的人失败,问获胜方是谁/是否存在先手必胜策略等等。
游戏的前提是,默认“双方都最聪明”,对于每一步,两方都能给出最优策略。因此,游戏的情形,可以说是一种“胜负手”的转移。若先手状态 f ( n ) f(n) f(n),在先手操作后, f ( n ) f(n) f(n)可以变成 f ( m ) f(m) f(m),且 f ( m ) f(m) f(m)是必败态,则 f ( n ) f(n) f(n)为必胜态。因此,双方的目的就是不断将局面转移到“必败态”,使得对手下一步无法操作。
一、热身
Roy&October之取石子
共有 n n n 个石子,两人每次都只能取 p k p^k pk 个( p p p 为质数, k k k 为自然数,且 p k p^k pk 小于等于当前剩余石子数),谁取走最后一个石子,谁就赢了。
结论:当且仅当 n n n 为6的倍数时,先手必败。
这是一道难度较低的入门博弈题。一个常用技巧是对于小数据进行枚举:我们可以发现, n = 1 ( 即 p 0 ) , 2 , 3 , 4 ( 即 2 2 ) , 5 n=1(即p^0),2,3,4(即2^2),5 n=1(即p0),2,3,4(即22),5 时,先手都可以一次性取完石子,先手必胜。而 n = 6 n=6 n=6 时,由于 6 = 2 × 3 6=2×3 6=2×3 ,不存在 p k p^k pk 满足要求,故先手必败。
因此我们可以推演出:对于任意 6 x = 2 × 3 × x 6x=2×3×x 6x=2×3×x,不存在满足条件的 p k p^k pk可以一次取完,因此,取走一次后必然形成 6 x ′ + k , k ∈ [ 1 , 5 ] 6x'+k,k∈[1,5] 6x′+k,k∈[1,5] 的情况,则后手可以拿走 k k k 个,不断把不利的局面转移给先手,最终拿走 1 , 2 , 3 , 4 , 5 1,2,3,4,5 1,2,3,4,5 中的一个数,获胜并结束比赛。
模板题:https://www.luogu.com.cn/problem/P4018
变形
共有 n n n 个石子,两人每次都只能取 p k p^k pk个( p p p 为质数,k=0或1,且 p k p^k pk小于等于当前剩余石子数),谁取走最后一个石子,谁就赢了。
结论:当且仅当 n n n 为4的倍数时,先手必败。
有了前一题的基础,我们继续枚举:当 n = 1 , 2 , 3 , 5 , 7 n=1,2,3,5,7 n=1,2,3,5,7 时,直接取完,先手必胜; n = 4 n=4 n=4 时,脑补排列可得先手必败; n = 6 n=6 n=6 时,可以取走两个转移到必败态$ n=4$ ,先手必胜; n = 8 n=8 n=8 时,可能到达的状态仅有 n = 4 n=4 n=4 为必败点,需要取走4个,为非法移动,故先手必败。
对于一个非质奇数,我们可以付出不多于3的代价将它转移为 4 x 4x 4x状态,故所有奇数都是必胜态。那么,只需要证明,对于一个偶数 n n n ,只有 n = 4 x n=4x n=4x 时必败。显然, n = 4 x + 2 n=4x+2 n=4x+2 时只需代价2就可以完成转移,而 4 x + 4 4x+4 4x+4不可能转移到 4 x 4x 4x,所有 4 x ′ 4x' 4x′ 都是必败态。
链接:https://www.luogu.com.cn/problem/P4860
二、Nim游戏
n n n堆石子,每堆有 a i a_i ai个。两个玩家必须轮流取走任意一堆的任意个(不含0)物品,取走最后一个物品的人获胜。
结论:当且仅当 a [ 1 ] ⊕ a [ 2 ] ⊕ a [ 3 ] ⊕ . . . ⊕ a [ n ] = 0 a[1] ⊕ a[2] ⊕ a[3] ⊕ ... ⊕ a[n] = 0 a[1]⊕a[2]⊕a[3]⊕...⊕a[n]=0 时,先手必败。
证明:
我们需要证明——
1、没有后继状态的状态是必败状态。
2、 a [ 1 ] ⊕ a [ 2 ] ⊕ a [ 3 ] ⊕ . . . ⊕ a [ n ] ≠ 0 a[1] ⊕ a[2] ⊕ a[3] ⊕ ... ⊕ a[n] ≠ 0 a[1]⊕a[2]⊕a[3]⊕...⊕a[n]=0时,存在一种取法,使得 a [ 1 ] ⊕ a [ 2 ] ⊕ a [ 3 ] ⊕ . . . ⊕ a [ n ] = 0 a[1] ⊕ a[2] ⊕ a[3] ⊕ ... ⊕ a[n] = 0 a[1]⊕a[2]⊕a[3]⊕...⊕a[n]=0 。
3、 a [ 1 ] ⊕ a [ 2 ] ⊕ a [ 3 ] ⊕ . . . ⊕ a [ n ] = 0 a[1] ⊕ a[2] ⊕ a[3] ⊕ ... ⊕ a[n] = 0 a[1]⊕a[2]⊕a[3]⊕...⊕a[n]=0时,不存在某种移动使得 a [ 1 ] ⊕ a [ 2 ] ⊕ a [ 3 ] ⊕ . . . ⊕ a [ n ] = 0 a[1] ⊕ a[2] ⊕ a[3] ⊕ ... ⊕ a[n] = 0 a[1]⊕a[2]⊕a[3]⊕...⊕a[n]=0 。
当以上三条得证时,随着玩家操作,异或和必然不断在0和非0之间转换,则初始为0时,经过偶数次变换,还是为0,先手必败。
证明1:没有后继的状态,即 a [ 1 ] = a [ 2 ] = a [ 3 ] = . . . = a [ n ] = 0 a[1]=a[2]=a[3]=...=a[n] = 0 a[1]=a[2]=a[3]=...=a[n]=0。此时,满足 a [ 1 ] ⊕ a [ 2 ] ⊕ a [ 3 ] ⊕ . . . ⊕ a [ n ] = 0 a[1] ⊕ a[2] ⊕ a[3] ⊕ ... ⊕ a[n] = 0 a[1]⊕a[2]⊕a[3]⊕...⊕a[n]=0。
证明2:设 a [ 1 ] ⊕ a [ 2 ] ⊕ a [ 3 ] ⊕ . . . ⊕ a [ n ] = k a[1] ⊕ a[2] ⊕ a[3] ⊕ ... ⊕ a[n] = k a[1]⊕a[2]⊕a[3]⊕...⊕a[n]=k,将它们的二进制计算以竖式排列,由异或的定义, k k k的二进制最高位 i d x idx idx 上必然有奇数个 1 1 1。取出一个满足 i d x idx idx 位上为 1 1 1的 a [ i ] a[i] a[i],将 a [ i ] a[i] a[i]改变成 t = a [ i ] ⊕ k t=a[i]⊕k t=a[i]⊕k。
∵ a [ 1 ] ⊕ a [ 2 ] ⊕ a [ 3 ] ⊕ . . . ⊕ a [ i ] ⊕ . . . ⊕ a [ n ] = k ∵a[1] ⊕ a[2] ⊕ a[3] ⊕ ...⊕a[i]⊕... ⊕ a[n] = k ∵a[1]⊕a[2]⊕a[3]⊕...⊕a[i]⊕...⊕a[n]=k
∴ a [ 1 ] ⊕ a [ 2 ] ⊕ a [ 3 ] ⊕ . . . ⊕ ( a [ i ] ⊕ k ) ⊕ . . . ⊕ a [ n ] = k ⊕ k = 0 ∴a[1] ⊕ a[2] ⊕ a[3] ⊕ ...⊕(a[i]⊕k)⊕... ⊕ a[n] = k⊕k=0 ∴a[1]⊕a[2]⊕a[3]⊕...⊕(a[i]⊕k)⊕...⊕a[n]=k⊕k=0
又 ∵ a [ i ] ∵a[i] ∵a[i]与 k k k最高位相同,∴ t < a [ i ] ⊕ k t<a[i]⊕k t<a[i]⊕k
即:从第 i i i堆石子中拿走a[i]-(a[i]⊕k)个石子,即可将该状态转换为满足 a [ 1 ] ⊕ a [ 2 ] ⊕ a [ 3 ] ⊕ . . . ⊕ a [ n ] = 0 a[1] ⊕ a[2] ⊕ a[3] ⊕ ... ⊕ a[n] = 0 a[1]⊕a[2]⊕a[3]⊕...⊕a[n]=0 的状态。
证明3:对于任意 x x x, x ⊕ 0 = x x⊕0=x x⊕0=x,因此对左式异或任意不为0的值去改变一堆石子数,右边必然不为0。
模板题:https://www.luogu.com.cn/problem/P1247
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
int n, a[N];
int main() {
cin >> n;
int tot = 0;
for (int i = 0; i < n; ++i) {
cin >> a[i];
tot ^= a[i];
}
if (!tot) cout << "lose";
else {
for (int i = 0; i < n; ++i) {
if ((a[i] ^ tot) < a[i]) {
cout << a[i] - (a[i] ^ tot) << ' ' << i + 1 << '\n';
a[i] ^= tot;
break;
}
}
for (int i = 0; i < n; ++i) {
cout << a[i] << ' ';
}
}
return 0;
}
三、由Nim到SG定理
首先,介绍一下前文提到的“先手必胜"和”先手必败“(即后手必胜)的官方名——
N-状态(next player):先手必胜,对于该点,下一个行动的玩家将会获胜。所谓“必胜点”。
P-状态(previous player):后手必胜,对于该点,前一个行动的玩家将会获胜。所谓“必败点”。
对于N-状态和P-状态,有如下性质:
- 所有终结点是P-状态
- 一个点为P-状态,当且仅当它的所有后继都为N-状态;
- 一个点为N-状态,当且仅当它的后继存在一个P-状态;
我们将博弈过程抽象为一张有向无环图,即从某一顶点出发,不断转移到下一状态,直到无路可走。
(一种N-P-状态转移示意)
理解到这里以后,引入 m e x 函 数 mex函数 mex函数 和 S G 函 数 SG函数 SG函数 的概念:
定义 m e x 函 数 mex函数 mex函数的值为不属于集合 S S S中的最小非负整数,
mex(S) = min{x} (x∉S,x∈N)
例: m e x { 0 , 2 , 3 } = 1 mex\{0,2,3\}=1 mex{0,2,3}=1, m e x { 1 , 2 , 3 , 6 , 7 } = 4 mex\{1,2,3,6,7\}=4 mex{1,2,3,6,7}=4, m e x { } = 0 mex\{\}=0 mex{}=0。
定义 S G ( x ) SG(x) SG(x) 表示 x x x 后继状态 x 1 、 x 2 、 . . . 、 x n x_1、x_2、...、x_n x1、x2、...、xn ( x > x i ) (x>x_i) (x>xi)的 S G SG SG 函数集合的 m e x mex mex值。
SG(x) = mex{SG(x1),SG(x2),…,SG(xn)}
SG[0] = 0
当 S G ( x ) = 0 SG(x)=0 SG(x)=0 时,即它已经无路可走,则此时的 x x x为P-状态。
借用参考链接第二位的博主@Enstein_Jun 的一个实例:
取石子问题
有1堆n个的石子,每次只能取{ 1, 3, 4 }个石子,先取完石子者胜利,那么各个数的SG值为多少?
SG[0]=0,f[]={1,3,4} (f表示可用改变量的状态集)
x=1 时,可以取走1 - f{1}个石子,剩余{0}个,所以 SG[1] = mex{ SG[0] }= mex{0} = 1;
x=2 时,可以取走2 - f{1}个石子,剩余{1}个,所以 SG[2] = mex{ SG[1] }= mex{1} = 0;
x=3 时,可以取走3 - f{1,3}个石子,剩余{2,0}个,所以 SG[3] = mex{SG[2],SG[0]} = mex{0,0} =1;
x=4 时,可以取走4- f{1,3,4}个石子,剩余{3,1,0}个,所以 SG[4] = mex{SG[3],SG[1],SG[0]} = mex{1,1,0} = 2;
x=5 时,可以取走5 - f{1,3,4}个石子,剩余{4,2,1}个,所以SG[5] = mex{SG[4],SG[2],SG[1]} =mex{2,0,1} = 3;
以此类推…
x 0 1 2 3 4 5 6 7 8…
SG[x] 0 1 0 1 2 3 2 0 1…
由上述实例我们就可以得到SG函数值求解步骤,那么计算1~n的SG函数值步骤如下:
1、使用 数组f 将 可改变当前状态 的方式记录下来。
2、然后我们使用 另一个数组 将当前状态x 的后继状态标记。
3、最后模拟mex运算,也就是我们在标记值中 搜索 未被标记值 的最小值,将其赋值给SG(x)。
4、我们不断的重复 2 - 3 的步骤,就完成了 计算1~n 的函数值。
sg函数代码:
int f[N],SG[MAXN],vis[MAXN];
void getSG(int n){
memset(SG,0,sizeof(SG));
//SG[0]=0
for(int i = 1; i <= n; i++){
memset(vis,0,sizeof(vis));
for(int j = 0; f[j] <= i && j <= N; j++)
vis[SG[i-f[j]]] = 1; //将i能到达的后继状态设为可到达
for(int j = 0;; j++) {
if(!vis[j]){ //求出当前后继状态集合中的mex,最小未被访问过的数
SG[i] = j;
break;
}
}
}
}
结合上述,引出 S G 定 理 SG定理 SG定理:
SG定理:
游戏和的SG函数
等于各个游戏SG函数的Nim和
。这样就可以将每一个子游戏分而治之,从而简化了问题。而Bouton
定理就是Sprague-Grundy
定理在Nim游戏中的直接应用,因为单堆的Nim游戏 SG函数满足 SG(x) = x。即:sg(X) = sg(x[1]) ^ sg(x[2]) ^ … ^ sg(x[n])
这时,再看nim博弈,实际上异或和为0时,就是sg(X)=0的情况。和上述对nim异或和为0为什么是P-状态的证明思路大致相同。因此,在很多情况下,求出sg函数并且分析sg(X)=0的情况,就是博弈题的突破口。
四、相关名词
对称博弈
阶梯波伊
反Nim博弈
Moore’s Nimk
树上博弈
图上博弈
巴士博弈
威佐夫博弈
(待补充)
参考资料:
http://keyblog.cn/article-47.html
https://blog.csdn.net/luomingjun12315/article/details/45555495
https://blog.csdn.net/bestsort/article/details/88197959
http://oi-wiki.com/math/game-theory/