博弈论初步学习总结
2016-05-24 22:25
260 查看
没事扯两句
虽然在OI界好像博弈题并不是很多(还是说我见识少),然而在ACM中似乎是很常见的…刷多校看题典什么的都会遇到,然后题解又往往只有简略的一句话:”暴力dp即可”“暴力维护SG函数即可”这种.所以还是花了一个多星期学习了一下这个玄学的东西…
其实严格来说博弈论完全不能算是算法对吧…
算法资料
《由感性认识到理性认识——透析一类搏弈游戏的解答过程》by 张一飞 2002年国家集训队论文
《解析一类组合游戏》
by 王晓珂 2007年国家集训队论文
《组合游戏略述——浅谈 SG 游戏的若干拓展及变形》
by 贾志豪 2009年国家集训队论文
《取石子游戏类分析的分析讨论》
by 朱全民老师
Game Thoery
by Thomas S. Ferguson
学习流程与心得
学习时首先要明白,我们研究的游戏其实应该叫做“组合游戏”,这是一种双人之间进行的公平的完全信息博弈,并且一定可以在有限步数内结束(详细的概念见王晓珂论文).所以在双方都采取最优策略的前提下,一个状态要么是必胜态要么是必败态,没有第三种情况.而判定必胜态和必败态最原始的方法就是:
必胜态可以转移到必败态.
必败态只能转移到必胜态.
终止状态的胜负需由规则而定,多数是无法操作者败.
也有相当数量的题目,只要按照这个显然的性质暴力求解就可以过了.这种题目把博弈的外壳去掉之后实质就只是个简单的暴力dp了,一般来讲没什么技术含量.所以这种题不看论文也可以做.
要开始看论文的话..上面列举出的前三篇国家集训队论文都是非常优秀的,强烈建议按顺序仔细阅读.
张一飞的论文由浅入深地引出了异或运算及SG函数(虽然论文中只是叫做f函数),一开始引入二进制非常妙,不显得那么突兀.然而后来关于SG函数的证明一开始还是会让人有些不知所措的.总之看完一遍之后要记住的结论还是比较简单的:
当前状态的SG值是所有后继状态的SG值构成的集合中不包含的最小的自然数(终止状态的SG值为0).
SG值为0的状态为必败态,非0的状态为必胜态(注意这里讨论的问题默认都是无法操作者败).
多个子游戏的和的SG值为各个子游戏SG值的异或和.
至于证明,论文中都有.
所以怎么理解这个东西呢?
说实话,这个SG函数为何这么神奇,或者说前人是怎么研究出它的,确实让人有些摸不着头脑.但是既然这个东西好用,而且我们也看过一次证明了,就不必太钻牛角尖了.后面的博弈模型中也会有一些比较无厘头的结论,但是既然能够证明了,我们也不必纠结那么多,说难听点记住一个结论就行了.
到此,可以把博弈问题分为一类:
暴力维护状态的必胜态、必败态信息或者SG值.
如果一步操作会把游戏分为几个子游戏,那就要用到SG了,否则就只需要必胜态、必败态的信息了.
然后继续看王晓珂的论文…这里面会讲到博弈中很重要的转化思想,而在朱全民老师整理的那一篇《取石子游戏类分析的分析讨论》中整合了许多经典的取石子游戏模型,这两篇可以交叉阅读.然后贾志鹏的论文中还介绍了翻硬币游戏、无向图删边游戏等等(说实话这篇我没有完全吃透).
这里我比较作死地整理一下常见的博弈游戏模型:
Nim Game
最经典最基础的博弈.
nn堆石子,双方轮流从任意一堆石子中取出至少一个,不能取的人输.
对于一堆xx个石子的情况,容易用归纳法得到SG(x)=xSG(x)=x.
所以所有石子个数的异或和为0是必败态,否则为必胜态.
Bash Game
每人最多一次只能取mm个石子,其他规则同Nim Game.
依旧数学归纳…SG(x)=x mod (m+1)SG(x)=x\ mod\ (m+1).
NimkNim_k Game
每人一次可以从最多kk堆石子中取出任意多个,其他规则同Nim Game.
结论:在二进制下各位上各堆石子的数字之和均为(k+1)(k+1)的倍数的话则为必败态,否则为必胜态.
这个证明要回到原始的方法上去.
Anti-Nim Game
似乎又叫做Misère Nim.
不能取的一方获胜,其他规则同Nim Game.
关于所谓的”Anti-SG游戏”及”SJ定理”贾志鹏的论文上有详细说明,不过似乎遇到并不多.
结论是一个状态是必胜态当且仅当满足以下条件之一:
SG值不为0且至少有一堆石子数大于1;
SG值为0且不存在石子数大于1的石子堆.
Staircase Nim
每人一次可以从第一堆石子中取走若干个,或者从其他石子堆的一堆中取出若干个放到左边一堆里(没有石子的石子堆不会消失),其他规则同Nim Game.
这个游戏的结论比较神奇:
当且仅当奇数编号堆的石子数异或和为0时为必败态.
简单的理解是从偶数编号堆中取石子对手又可以放回到奇数编号堆中,而且不会让对手不能移动.比较意识流,然而可以归纳证明.
Wythoff Game
有两堆石子,双方轮流从某一堆取走若干石子或者从两堆中取走相同数目的石子,不能取的人输.
容易推理得出对任意自然数kk,都存在唯一的一个必败态使得两堆石子数差为kk,设其为Pk=(ak,bk)P_k=(a_k,b_k),表示石子数分别为ak,bk(ak⩽bk)a_k,b_k(a_k\leqslant b_k).
那么aka_k为在Pk0(k0<k)P_{k_0}(k_0中未出现过的最小自然数,bk=ak+kb_k=a_k+k.
数学班的说,用Betty定理以及显然的单调性就可以推出神奇的结论:
ak=⌊k⋅5√+12⌋,bk=⌊k⋅5√+32⌋a_k=\lfloor k\cdot \frac{\sqrt5+1}{2}\rfloor,b_k=\lfloor k\cdot \frac{\sqrt5+3}{2}\rfloor.
Take & Break
有nn堆石子,双方轮流取出一堆石子,然后新增两堆规模更小的石子堆(可以没有石子),无法操作者输.
这个游戏似乎只能暴力SG,知道一下就好.
树上删边游戏
给出一个有nn个结点的树,有一个点作为树的根节点,双方轮流从树中删去一条边边,之后不与根节点相连的部分将被移走,无法操作者输.
结论是叶子结点的SG值为0,其他结点SG值为其每个儿子结点SG值加1后的异或和,证明也并不复杂.
下面两个游戏我不太会,于是偷懒引用贾志豪《组合游戏略述——浅谈 SG 游戏的若干拓展及变形》中的内容了.
翻硬币游戏
nn枚硬币排成一排,有的正面朝上,有的反面朝上。
游戏者根据某些约束翻硬币(如:每次只能翻一或两枚,或者每
次只能翻连续的几枚),但他所翻动的硬币中,最右边的必须是
从正面翻到反面。
谁不能翻谁输。
需要先开动脑筋把游戏转化为其他的取石子游戏之类的,然后用如下定理解决:
局面的 SG 值等于局面中每个正面朝上的棋子单一存在时的 SG 值的异或和。
无向图删边游戏
一个无向连通图,有一个点作为图的根。
游戏者轮流从图中删去边, 删去一条边后,不与根节点相连的部
分将被移走。
谁无路可走谁输。
对于这个模型,有一个著名的定理——Fusion Principle:
我们可以对无向图做如下改动:将图中的任意一个偶环缩成一个新
点,任意一个奇环缩成一个新点加一个新边;所有连到原先环上的边全
部改为与新点相连。 这样的改动不会影响图的 SG 值。
以上.
所以博弈的题目解法还是比较单一的:
暴力dp,是否要用到SG得看一次操作后是否会将游戏划分为几个子游戏.
转化为经典的博弈模型.
当然,还有些题目是这两种方法都搞不了的,那就只有上杀手锏——打表找规律了.
然后就是多写几道题啰.怪我没有把写过的题目放在这里.
另外,在hzwer的博客里似乎只找到了两道博弈的省选题,让我有点不知所措…所以在OI界博弈还只是很小的一块喽?
初步学习就到这里告一段落喽~~~
(P.S. 上面放出来的Game Theory是权威的一部大长篇,不过暂时我觉得没必要看了…)
相关文章推荐
- 剑指offer(三十四)之二叉树的镜像
- JS闭包理解
- Java 网络编程 练习
- 使用FFmpeg将文件转为ts
- C++作业6—数组操作/数组合并
- Java国际化
- java使用中科院分词器出现not valid license错误
- 系统对象和对象权限
- hadoop
- 复习
- 监听儿童手表
- 原型模式
- 个人工作总结01(第二阶段)
- 对Unity协程的深入理解
- lambda 函数在C++中的用法
- 字符串的排列
- go学习
- 对yield return的理解
- HDU5691 Sitting in Line(百度之星2A)
- 点击按钮背景慢慢扩大com.balysv.materialripple.MaterialRippleLayout