zoukankan      html  css  js  c++  java
  • 博弈论总结

    博弈论总结

    开头&一些基本性质

    本文的大部分内容来自于(YMD)的课件。((orz YMD))

    一、必胜点和必败点

    • (P)点:必败点,在双方都聪明无比的情况下(比如(zsy)(ppl)在玩游戏),当前先手的人必败的情况。
    • (N)点:必胜点,在双方操作都正确的情况下先手必胜的位置。

    几个性质

    • 所有的终止位置都是必败点(P)(我们认为这个是公理,即所有推导都在这个性质成立的基础上进行。
    • 从任何一个必胜点(N)操作,至少有一种方法可以达到一个必败点(P)
    • 从一个必败点(P)出发,只能够到达一个必胜点(N)

    二、无偏博弈

    无偏博弈是一类任意局势对于游戏双方都是平等的回合制双人游戏。平等的含义是当前的所有可行的走法仅仅只依赖与当前的局势,而与当前谁移动无关。换而言之,两个人除了先后手的区别之外就不存在任何区别。除此之外,还需要满足一下性质:

    • 完全信息,任何一个游戏者都能够知晓整个游戏状态。
    • 无随机行动,所有的行动都会转移到一个唯一确定的状态。
    • 在有限步内游戏会终止,此时有唯一的胜者。

    三、常见模型

    • 巴什博奕((Bash Game))
    • 威佐夫博弈((Wythoff Game))
    • 尼姆游戏((Nim Game))
    • (Anti-SG)游戏
    • (Multi-SG)游戏
    • (Every-SG)游戏
    • 翻硬币游戏
    • 树上删边游戏

    巴什博奕((Bash Game))

    基本问题

    有一堆石子,总个数是(n),两名玩家轮流在石子堆中拿石子,每次至少取(1)个,至多取(m)个。取走最后一个石子的玩家为胜者。判定先手和后手谁胜。

    解决方法

    如果((m+1)|n)则先手必败,否则先手必胜。

    证明

    假设((m+1)|n),那么假设先手拿走了(x)个,那么后手必定可以拿走((m+1)-x)个,这样子无论怎么拿,剩下的石头个数都将是(m+1)的倍数。那么最后一次取的时候石头个数必定还剩下(m+1)个,无论先手拿多少个,都会剩下石头,此时后手必定可以将剩下的所有石头取光从而获胜。

    否则的话,先手可以取走模(m+1)余数个数个石头,此时模型转换为了先手面对((m+1)|n)个石头的情况,也就是后手必败,即先手必胜。

    题目&代码

    HDU1846 Brave Game

    威佐夫博弈((Wythoff Game))

    基本问题

    有两堆石子,石子数可以不同。两人轮流取石子,每次可以在一堆中取,或者从两堆中取走相同个数的石子,数量不限,取走最后一个石头的人获胜。判定先手是否必胜。

    解决方法

    这个东西意义不是很大,打表找规律之后可以发现先手必败的状态一定形如(([i imesphi],[i imesphi^2]))。其中(phi=frac{sqrt{5}+1}{2})([x])表示不大于(x)的最大整数。一些证明可以参考这个神仙博主的博客

    题目&模板

    洛谷2252&HDU1527 取石子游戏

    尼姆博弈((Nim Game))

    基本问题

    有三堆石子,两人轮流取,每次可以从一堆中取走任意数量个石子,至少取走一个,问先后手谁胜。

    一般推广:有(n)堆石子(x_1,x_2,x_3,...,x_n),两人轮流取,每次可以从任意一堆石子中取走至少一个石子,问先后手谁胜。

    解决方法

    方法很简单,直接求所有(x_i)的异或和,如果异或和为(0)则先手必败,否则先手必胜。形式化的表达即当且仅当(x_1oplus x_2oplus x_3oplus...oplus x_n=0)时,先手必败。

    同理,也就是所以异或和为(0)的状态是(P)状态,所有异或和非(0)的是(N)状态。

    证明(伪证):

    首先当没有石子的时候,先手必败,此时所有石子的异或和为(0),这个是(P)状态。

    接下来我们证明任意一个(N)状态至少能够达到一个(P)状态。

    假设当前所有石子个数的异或和为(k),即(oplus_{i=1}^nx_i=k),那么,必定存在一个(x_i)满足(x_i)二进制位上存在(k)的最高位,并且不难证明(x_ioplus k<x_i),那么,将(x_i)异或上(k)之后,剩下所有的数的异或和恰好为(0),又回到了一个(P)状态。

    而一个(P)状态的异或和为(0),任何一个数减小之后异或和一定不为(0),所以可以证明任何一个(P)状态的后继状态都是(N)状态。

    综上,异或和为(0)的状态先手必败,其他情况先手必胜。

    拓展形式

    • 每次取的石子数存在上界(m)

      这个是(Bash Game+Nim Game),只需要把所有石子按照(m+1)取模再考虑(Nim)游戏就好了。

    • 每次允许从(k)堆石子中取((Nim_k))

      我们一般考虑的情况是(Nim_1),我们的解法是考虑(2)进制下的异或和是否为(0),而异或和是不进位的加法,同理,对于(Nim_k)的情况,我们考虑(k+1)进制下每一位不进位加法的结果,如果每一位都是(0)的话就是(P)局面,否则是(N)局面。

    • 阶梯博弈:博弈在阶梯上进行,每次可以将一堆的若干式子移动到上一阶去,不可操作者输。

      忽略所有的偶数阶梯,只留下奇数阶梯,转化为普通的(Nim)游戏。大致的思路是这样的:首先终止状态一定是所有石子都在(0)号阶梯,即一个偶数阶梯。那么如果对方移动了一个偶数阶梯上的石子,那么你可以在移动结束的那个奇数阶梯,直接把等数量的石子继续向前移动,这样子可以保证偶数阶梯上的石子对于结果没有任何影响。那么如果移动的是一个奇数阶梯,因为偶数阶梯是没有影响的,所以你可以认为移动奇数阶梯就是直接被移走了,那么这就是一个普通的(Nim)游戏了。

    题目&模板

    洛谷2197 (Nim)游戏裸题

    BZOJ1299 Nim游戏变形

    POJ1704 阶梯博弈变形

    (SG)定理和(SG)函数

    • (Sprague-Grundy)定理:所有一般胜利下的无偏博弈(定义在上面)都能够转化成尼姆数表达的尼姆堆博弈,一个无偏博弈的尼姆值定义为这个博弈的等价尼姆数。(抄自(YMD)课件)
    • (SG)函数:对于每一个状态的一个尼姆数的函数又被称作(Sprague-Grundy)函数。

    翻译成人话就是:对于当前游戏(X),它可以拆分成若干个子游戏(x_1,x_2,x_3,...,x_n)。那么(SG(X)=SG(x_1)oplus SG(x_2)oplus...oplus SG(x_n))

    接下来定义(mex)运算,(mex)运算是对于一个集合(S)而言的,(mex(S))表示的是最小的、不属于集合(S)的非负整数。例如(mex{1,2,3}=0,mex{phi}=0)。那么我们有运算(SG(x)=mex{SG(y),<x,y>in E}),其中(E)是边集。即对于当前状态(x)(SG)函数,它的值定义为所有的后继状态的(mex)值。对于(SG)函数为(0)的位置一定是(P)位置,(SG)函数非(0)的位置是(N)位置。

    这里直接空说很不好,我们举个例子。

    HDU1848 Fibonacci again and again,为了节约篇幅,直接戳链接看题目&题解&代码。

    事实上,注意"后继"这个词语,我们不难发现上述的东西可以理解为一个(DAG)上的问题。

    (Anti-SG)游戏&(SJ)定理

    基本问题

    决策集合为空者的操作者胜利。翻译成(Nim)一点的问题就是,给定(n)堆式子,每次每个人可以从任意一堆石子中拿走不少于一个的石子,拿走最后一个石子的人输。

    解决方法

    (SJ)定理:对于一个(Anti-SG)游戏,如果我们规定当前局面中所有单一游戏的(SG)(0)时,游戏结束,则先手必胜的条件为:

    • 游戏的(SG)值不为(0),且存在一个单一游戏的(SG)值大于(1)
    • 游戏的(SG)值为(0),且不存在一个单一游戏的(SG)值大于(1)

    题目&模板

    BZOJ1022 (Anti-SG)模板题

    (Multi-SG)游戏

    基本模型

    决策集合为空的操作者输。一个单一游戏的后继可以是多个单一游戏。还是写成(Nim)一点的式子,给定你(n)堆石子,每次可以取走任意数量个,或者将一堆式子拆分成两堆(事实上更多也是可行的)非空石子,不能操作者输,判定胜负。

    解决方法

    还是可以使用(SG)函数解决,举个例子,比如当前存在一堆(3)个石子,那么可以直接走(0,1,2,3)个石子,也可以拆分成((1,2))两堆,因此(SG(3)=mex{SG(0),SG(1),SG(2),SG(3),SG((1,2))=SG(1)oplus SG(2)})

    那么这个问题本质上还是一个(Nim)游戏,可以直接用(SG)函数解决。

    同时,对于这样每次可以拆分两堆的(Multi-SG)游戏,打表后发现有这样一个性质:

    [SG(x)=egin{cases} x-1&(x mod 4=0)\ x&(x mod 4=1&2)\ x+1&(x mod 4=3) end{cases} ]

    题目&模板

    HDU3032 (Multi-SG)模板题

    BZOJ2940 简单的(Multi-SG)题目

    BZOJ1188 有些困难的(Multi-SG)模型

    BZOJ3576 有点难度的(Multi-SG)变形

    (Every-SG)游戏

    基本模型

    对于没有结束的任何一个单一游戏,操作者必须对其进行一步操作,无法操作者输。

    解决方法

    所有游戏都是独立的,并且我们发现无法操作者输,而同时又在进行多个游戏。因此,我们知道胜负情况只与最后结束的游戏的胜负情况相关。既然只与最后结束的游戏相关,那么我们这样分析:首先对于一个能够取得胜利的游戏,我们必定会取得胜利,这样一定不会让结果更差,因为只要赢了,这局游戏就一定不会让自己输。那么对于所有单个游戏的胜负情况,我们一定可以判定,但是对于整个(Every-SG)的情况,我们只能够通过最后结束的游戏判定。所以,对于一个我们必胜的游戏,我们一定会想办法将其尽可能的向后拖,即我们期望它尽可能完的结束;反过来,对于一个必败的游戏,我们一定会让他尽可能早的结束。这几句推论正确的理由都是所有游戏都是互相独立的。

    那么,我们首先可以判定出所有位置是(N)点还是(P)点,然后根据必胜和必败的关系,我们必定要决策步数最小还是步数最大,那么这个就非常类似于一个(min-max)搜索。至于(N)点和(P)点的判定我们可以很容易的用(SG)函数表示出来。我们定义(step(x))为状态(x)时(在满足(N/P)的条件下)的步数,我们可以得到这样一个转移:

    [step(x)=egin{cases} 0&u=End\ max{step(v)},<u,v>in E&uin N,vin P\ min{step(v)},<u,v>in E&uin P end{cases} ]

    不难发现对于一个(P)状态,(step)一定是偶数,对于一个(N)状态,(step)一定是一个奇数。那么对于这样一个游戏,先手必胜的条件就变成了当且仅当所有单一游戏的最大(step)是一个奇数。

    题目&模板

    HDU3595 观察性质后直接用(Every-SG)求解

    翻硬币游戏

    题目

    (n)枚硬币排成一排,依次编号(1)(N),有的正面朝上,有的反面朝上。现在按照一定的规则翻硬币(比如每次只能翻一枚或者两枚,或者每次只能翻动连续的几枚),但是强制要求最靠右的硬币必须从正面被翻到了反面。操作集合为空者负。

    解决方法

    结论是这样的:当前局面的(SG)值是所有正面朝上的硬币单独存在时的(SG)值的异或和。

    证明?我也不会啊。可以感性理解一下,无论如何最右边的硬币都要翻,它翻了之后必定改变前面的状态,但是前面的状态是什么似乎和之前的状态无关(假装能够说服我自己),之和之前的状态和现在状态的差别(也就是看成(01)串后的异或和)相关,所以你可以把游戏拆分成所有正面朝上的硬币的子游戏。

    如果您想参考更多翻硬币的规则,可以戳这里

    链接中给出这么多游戏的主要目的是因为直接使用(SG)函数求解效率太低,很多时候利用(SG)函数打表找规律才是最好的方法。

    树的删边游戏

    题目

    给定一个(n)个节点的有根树,两人轮流删边,删去边之后,不和根节点联通的部分都会被移除。不能操作者输,判断胜负。

    解决方法

    结论:定义叶子节点的(SG)值为(0),其他所有节点的(SG)值为它所有儿子的(SG)值加(1)后的异或和。

    证明:我也懒得会,没有太多的意义,如果有兴趣看可以戳这里

    结尾

    对于这一部分的博弈,这些东西都是比较常见的博弈模型。它们主要利用(SG)函数求解,换而言之,(SG)函数就是这篇文章中所有博弈游戏的灵魂。所有的一切都是利用(SG)函数区分(N/P)状态,利用(SG)函数,也可以得到很多题目不会差于对抗搜索复杂度的算法。

    但是有很多的博弈题目似乎并用不上(SG)函数,或者说很难用上,这个时候的解决方法一般就是要么直接打表找规律,要么通过分析和构造,找到先手必胜的条件再来进行判断。这些非常见的博弈模型也就不是我在这里能够穷举完的啦。

  • 相关阅读:
    AngularJS总结
    网页的颜色表示方法
    计算机中的字符编码
    计算机中的进制
    常用的HTML 标签二
    常用的HTML标签
    常用的字符实体标记
    一个请求的访问流程
    http请求访问过程
    codeforces 269C Flawed Flow(网络流)
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9495131.html
Copyright © 2011-2022 走看看