博弈算法 之 SG 函数的运用

来源:互联网 发布:政府高官子女知乎 编辑:程序博客网 时间:2024/06/05 04:10


SG函数简介:

如果我们把游戏中的某一个局面看作一个顶点,把局面之间的转换用边来表示,那么很多游戏都可以转

化成图游戏模型。

图游戏模型 给定有向无环图G=(V,E)和一个起始点,双方轮流行动。每个人每次可以从当前点出发沿着

一条有向边走到另外一个点。谁无法走了谁就输。

一些图游戏可以通过Sprague-Grundy函数来判定先手的胜负情况(简称SG函数)。

SG函数 一个图G=(V,E)的SG函数g,是定义在v上的一个非负整数函数:
g(x)=min{n>=0 | n≠g(y) for <x,y>∈E}
如果x的出度为0,那么g(x)=0。(边界条件)


SG函数内涵:

g(x)就是x的后继点的SG值中没有出现过的最小值。

这样定义有什么好处呢?我们把一个图的当前状态值定义为游戏者处在的这个点的SG值。

如果游戏者处在一个点x,g(x)≠0。那么0, 1, …, g(x)-1这些数必然都出现在x的后继节点的SG值中,而

游戏者可以走到这些点中的任意一个。也就是说:游戏者可以通过一步走棋把图的当前状态值任意的

减小(当然必须保证状态值始终>=0)。
如果游戏者处在一个点x,g(x)=0。那么游戏者无论如何移动,下一个点的SG值都不等于0。


SG函数性质:

对于一个图游戏,如果图的当前状态等于0,那么先手必败,否则必胜。
证明:
如果当前点SG=0,先手无论怎么走,都会到达一个SG<>0的点;接着后手就能设法到达一个SG=0的点。

也就是说后手总是能移动,而先手总是处在SG=0的点。游戏不能无限的进行下去,一旦先手到达一个出

度等于0的点,游戏结束,先手败。
如果当前点SG≠0,先手可以走到一个SG=0的点,这样后手面对一个必败状态,所以先手必胜。


保龄球问题:

在一行中有n个木瓶,你和你的朋友轮流用保龄球去打这些木瓶,由于你们都是高手,每一次都可以准确

的击倒一个或相邻的两个木瓶,谁击倒最后一个剩余的木瓶谁将获得胜利。如果由你先打,请你分析,

你应该采取什么策略来确保赢得胜利。


为了更方便的看清楚问题的本质,我们用另一种方式来描述这个游戏。
最开始有一堆石子(n个),每一次你可以进行以下四种操作中的一种:
从中取出一颗石子
从中取出两颗石子
从一堆中取出一颗石子,并且将这一堆中余下的石子任意分成两堆(每堆至少一颗)
从一堆中取出两颗石子,并且将这一堆中余下的石子任意分成两堆(每堆至少一颗)


这四种操作,实际上就依次对应于原来游戏中的以下四种击倒法:
击倒一段连续的木瓶中最靠边的一个
击倒一段连续的木瓶中最靠边的连续两个
击倒一段连续的木瓶中不靠边的一个
击倒一段连续的木瓶中不靠边的连续两个


注:⊕= ^;

把局面看作顶点,游戏规则看作边,这是一个典型的图游戏。
如果当前局面被分成了M堆,(A1,A2,…,Am),则
SG(A1,A2,…,Am)=SG(A1)⊕SG(A2)⊕…⊕SG(Am)
显然, SG(0)=0
剩余一个时,只能取到0个,而SG(0)=0,所以SG(1)=1。
剩余两个时,可以取到0或1,其中SG(0)=0,SG(1)=1,
所以SG(2)=2
剩余三个时,我们可以把局面变成1或2或两堆均为1。
其中SG(1)=1,SG(2)=2,SG(1,1)=SG(1) ⊕ SG(1)=0,所以SG(3)=3
SG(4)可分解为{SG(2), SG(3),SG(2)⊕SG(1), SG(1)⊕SG(1)}                         ={2,3,3,0},所以SG(4)=1
对于任意一种局面P,的SG值为SG(P),为了赢得胜利,我们只需将他的局面变成Q,使得SG(Q)=0即可。


优化:

对于每一个N值,我们为了求出他的SG值, 时间复杂度为O(N) ,如果只要求你求出你第一步应该如何行动,

那么这种普通的方法需要O(N2)的复杂度,显然不能令我们满意。
这个问题看似已经解决,但我们可以进行优化。
事实上,我们通过观察较小的数的SG值,可以发现:
0 ~11的SG值为:0 1 2 3 1 4 3 2 1 4 2 6
12~23的SG值为:4 1 2 7 1 4 3 2 1 4 6 7
24~35的SG值为:4 1 2 8 5 4 7 2 1 8 6 7
36~47的SG值为:4 1 2 3 1 4 7 2 1 8 2 7
48~59的SG值为:4 1 2 8 1 4 7 2 1 4 2 7
60~71的SG值为:4 1 2 8 1 4 7 2 1 8 6 7
72~83的SG值为:4 1 2 8 1 4 7 2 1 8 2 7
并且从72开始,SG值以12为循环节,不断的重复出现,这样我们求出所有SG值的复杂度就降到了常数,

这样判断第一步的如何选择的复杂度就降为了O(N)。

0 0