转自:Sprague-Grundy Function-SG函数--博弈论(3)

公平游戏的Sprague-Grundy定理

公平游戏是一种双人游戏,在游戏中双方都有完整的信息,没有牵涉,任何状态的合法操作对双方来说都是相同的。

一个公平游戏可以抽象地用一个有向无环图来表示,这个图中每个点都对应这一个状态,每条有向边代表从一个状态到另一个状态的合法操作。

我们可以想象一个代币最初放在某个点上,然后两个玩家轮流将其从当前的点移动到它的后继点。当代币移动到汇点时游戏结束,汇点是一个没有出度的点,最后一个需要操作的玩家就是胜者。

P- 和 N-状态

如果双方都按照最佳策略进行游戏,我们可以将游戏中的每个状态依据其是先手必胜还是后手必胜分类。

一个先手胜状态被认为是一个N-状态(因为下一个玩家即将获胜),一个后手胜状态被认为是一个P-状态(因为前一个玩家即将获胜)

P-和N-状态归纳性地描述如下:

一个点v是P-状态当且仅当它的所有后继都为N-状态

一个点v是N-状态当且仅当它的一些后继是P-状态

这个归纳从汇点开始,汇点是P-状态因为它显然满足P-状态的要求。

游戏的P-和N-状态的信息提供了它的必胜策略。如果轮到我们且游戏处在一个N-状态,我们应该转移到一个P-状态。接着我们的对手就会被迫进入N-状态,依此类推。我们最终会移入一个汇点并获得胜利。

游戏的和

如果G1和G2 是公平游戏,那么他们的和G1 + G2是另一个公平游戏,玩法如下:每个回合,一个玩家选择G1, G2 中的一个(随便哪个他希望的)然后玩它,不碰另一个游戏。当 G1 和 G2都不能操作时游戏结束。

形式上,如果 G1 = (V1, E1) 和 G2 = (V2, E2)是游戏图,那么他们的和 Gsum = (Vsum, Esum) 规定为:

Vsum = V1 × V2,

Esum = {(v1v2, w1v2) | (v1, w1) ∈ E1} ∪ {(v1v2, v1w2) | (v2, w2) ∈ E2}.

现在,假定我们给出两个游戏G1 和 G2。如果我们只知道单个游戏的P-状态和N-状态我们能够正确地玩好游戏和G1 + G2吗?答案是否定的。不难看出两个P-状态的和总是P-状态,P-状态和N-状态的和总是N-状态。但是两个N-状态的和既可能是P-状态也可能是N-状态。因此,只知道单个游戏的P-状态和N-状态是不够的。

为了正确地玩好游戏和我们需要推广P-状态和N-状态,它就是Sprague-Grudy函数(或者简称为Grundy函数)。

The Sprague-Grundy function

Sprague-Grundy 函数

令N = {0, 1, 2, 3, ...} 为自然数的集合。Sprague-Grundy 函数给游戏中的每个状态分配了一个自然数。结点v的Grundy值等于没有在v的后继的Grundy值中出现的最小自然数。

形式上:给定一个有限子集 S ⊂ N,令mex S(最小排斥值)为没有出现在S中的最小自然数

mex S = min (N S).

现在,给定一个游戏图G=(V,E),其Sprague-Grundy函数g:V → N 归纳定义为

g(v) = mex {g(w) | (v, w) ∈ E}.

从G的汇点开始归纳,可知它的Grundy值为0

Sprague-Grundy函数满足两个重要性质:

点v是一个P-状态当且仅当g(v)=0

如果G = G1 + G2 且 v = v1v2 是G的一个状态,那么g(v) 为g(v1) 和 g(v2) 在二进制下的异或:

g(v) = g(v1) ⊕ g(v2).

运算⊕也称作nim和。举个例子,3 ⊕ 5 = 011 ⊕ 101 = 110 = 6。类似地,3 ⊕ 6 = 5 且 5 ⊕ 6 = 3。

不难利用归纳法证明上面两个性质。

根据这些性质有v = v1v2 是P-状态当且仅当g(v1) = g(v2), 因为这是唯一能够使得nim和为0的途径。

无疑,游戏的求和是满足交换律和结合律的运算,nim和运算也是。

因此,我们可以通过获知单个游戏的Grundy函数来正确地玩好任意数目游戏和。

我们的策略如下:如果轮到我们且游戏的Grundy值给出了一个非0的nim和,那么必然在游戏的某个组分中存在一个操作使得nim和变为0。我们应该执行这个操作,那么接着我们的对手就被迫再次使得nim和非0。最终,我们将成为在最后一个游戏执行最后一个操作的人,最后将nim和变为0.

The game of Nim

Nim游戏

最基本的公平游戏是Nim堆。一个Nim堆由确定数目代币组成。在每个回合,一个玩家从堆上拿走1到整堆中任意数目的代币。拿空整堆的人获得胜利。

这个游戏如果独立看是没有意义的:先手玩家可直接拿走所有代币并立即获得胜利!

但是如果我们将各种大小的Nim堆加在一起,我们就得到了著名的Nim游戏。

大小为n的Nim堆的Grundy值为n。因此,Nim游戏中每个状态的Grundy值为每堆大小的Nim和。

Games that decompose into sums of themselves

一些分解成自身和的游戏

Sprague-Grundy定理最自然的应用就是一些分解成自身和的一些游戏。

考虑下面这个游戏:有一个大小为m*n的棋盘,且有无限数目某特定形状的骨牌供应。在每个回合,玩家在棋盘上一个空位放置一个骨牌,不能放骨牌的玩家就是败者。

在游戏期间,棋盘会逐渐分成不同的区域,对其我们可以分别计算Grundy值。

再举个例子,考虑Grundy游戏。这个游戏的一个状态由一些不同大小的代币堆组成,一次操作由只取一堆并把它分成两个不相等的堆组成。当所有堆的大小只有1和2的时候游戏结束,因为它不能再分。

令g(n)为单个大小为n的堆的Grundy值。数列g(n)如下:

n:     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20...

g(n):0  0  1  0  2  1  0  2  1  0   2   1  3   2   1   3  2   4   3  0

比如:

当n等于1,2时已满足条件,即不能再取,也就没有下一个局面,所以g(1)={};所以G(1)={0,1,2,3,4...};

所以g(1)=0;同理g(2)=0;依次递推,g(3),g(4),g(5)等,

例如:g(6)={#(1,5),#(2,4)}={g(1)+g(5),g(2)+g(4)}=g(2,0);

所以G(6)={1,3,4,5,6...},所以g(6)=1;

此题的求法,具体参见我的博客的最下面求f(n)的值:http://www.cnblogs.com/hsqdboke/archive/2012/04/20/2459796.html

最新文章

  1. zookeeper在linux下自启动
  2. http://www.cnblogs.com/Lawson/archive/2012/09/03/2669122.html
  3. va_list结构体
  4. Struts2之提交对象数组至后台
  5. CSS的4种引入方式及优先级
  6. nlssort函数的用法以及参数
  7. jquery 的datatables插件问题
  8. C代码中如何调用C++ C++中如何调用C
  9. 《Linux内核设计与实现》读书笔记(十二)- 内存管理【转】
  10. 桶排序之python实现源码
  11. A题笔记(4)
  12. 小程序脚本语言WXS,你想要的都在这里了
  13. EasyUI 树菜单
  14. 使用pm2躺着实现负载均衡
  15. 小妖精的完美游戏教室——东方project,同人,自机
  16. redis学习笔记(面试题)
  17. 让Win2008+IIS7+ASP.NET支持10万并发请求
  18. 将svnserve部署为后台服务
  19. 如何勾选 servlet如何获取?
  20. android 播放视频时切换全屏隐藏状态栏

热门文章

  1. DELLR720 独立显卡DVI转VGA问题
  2. .Net强大的列表控件XPTable [转]
  3. 【PA2012】【BZOJ4289】Tax
  4. mobx 小结
  5. Nginx:事件模块
  6. 如何在 Linux 中找到你的 公网IP 地址
  7. Mac 下Versions的 svn无法上传 .a 文件的问题
  8. .net用url重写URLReWriter实现任意二级域名
  9. appium 学习和环境搭建
  10. ACM算法整理(不断补充ing)