zoukankan      html  css  js  c++  java
  • 【转载】【博弈论的总结】

    转自:http://www.cnblogs.com/celia01/archive/2011/11/15/2250171.html

    【以下内容为转载】

    上次做poj 1067的取石子游戏,只用到了whthoff博弈,未涉及到取石子的异或方法,今天重新搜索,整理了一遍。搜罗各种资料,加上自己整理,终于成篇啦!……噼里啪啦

     

    取石子问题

    有一种很有意思的游戏,就是有物体若干堆,可以是火柴棍或是围棋子等等均可。两个人轮流从堆中取物体若干,规定最后取光物体者取胜。这是我国民间很古老的一个游戏,别看这游戏极其简单,却蕴含着深刻的数学原理。下面我们来分析一下要如何才能够取胜。

    (一)巴什博奕(Bash Game):只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。

        显 然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜。因此我们发现了如何取胜的法 则:如果n=(m+1)r+s,(r为任意自然数,s≤m),那么先取者要拿走s个物品,如果后取者拿走k(≤m)个,那么先取者再拿走m+1-k个,结 果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜。总之,要保持给对手留下(m+1)的倍数,就能最后获胜。

    即,若n=k*(m+1),则后取着胜,反之,存在先取者获胜的取法。

    n%(m+1)==0. 先取者必败
        这个游戏还可以有一种变相的玩法:两个人轮流报数,每次至少报一个,最多报十个,谁能报到100者胜。

    从一堆100个石子中取石子,最后取完的胜。
    (二)威佐夫博奕(Wythoff Game):有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。
        这 种情况下是颇为复杂的。我们用(ak,bk)(ak ≤ bk ,k=0,1,2,...,n)表示两堆物品的数量并称其为局势,如果甲面对(0,0),那么甲已经输了,这种局势我们称为奇异局势。前几个奇异局势是: (0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20)。
        可以看出,a0=b0=0,ak是未在前面出现过的最小自然数,而 bk= ak + k,奇异局势有
    如下三条性质:

        1。任何自然数都包含在一个且仅有一个奇异局势中。
        由于ak是未在前面出现过的最小自然数,所以有ak > ak-1 ,而 bk= ak + k > ak-1 + k-1 = bk-1 > ak-1 。所以性质1。成立。
        2。任意操作都可将奇异局势变为非奇异局势。
        事实上,若只改变奇异局势(ak,bk)的某一个分量,那么另一个分量不可能在其他奇异局势中,所以必然是非奇异局势。如果使(ak,bk)的两个分量同时减少,则由于其差不变,且不可能是其他奇异局势的差,因此也是非奇异局势。
        3。采用适当的方法,可以将非奇异局势变为奇异局势。

        假 设面对的局势是(a,b),若 b = a,则同时从两堆中取走 a 个物体,就变为了奇异局势(0,0);如果a = ak ,b > bk,那么,取走b - bk个物体,即变为奇异局势;如果 a = ak , b < bk ,则同时从两堆中拿走 ak - ab - ak个物体,变为奇异局势( ab - ak , ab - ak+ b - ak);如果a > ak ,b= ak + k,则从第一堆中拿走多余的数量a - ak 即可;如果a < ak ,b= ak + k,分两种情况,第一种,a=aj (j < k),从第二堆里面拿走 b - bj 即可;第二种,a=bj (j < k),从第二堆里面拿走 b - aj 即可。

        从如上性质可知,两个人如果都采用正确操作,那么面对非奇异局势,先拿者必胜;反之,则后拿者取胜。

        那么任给一个局势(a,b),怎样判断它是不是奇异局势呢?我们有如下公式:
        ak =[k(1+√5)/2],bk= ak + k (k=0,1,2,...,n 方括号表示取整函数)
    奇 妙的是其中出现了黄金分割数(1+√5)/2 = 1。618...,因此,由ak,bk组成的矩形近似为黄金矩形,由于2/(1+√5)=(√5-1)/2,可以先求出j=[a(√5-1)/2],若 a=[j(1+√5)/2],那么a = aj,bj = aj + j,若不等于,那么a = aj+1,bj+1 = aj+1+ j + 1,若都不是,那么就不是奇异局势。然后再按照上述法则进行,一定会遇到奇异局势。

    (三)尼姆博奕(Nimm Game):有三堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取一个,多者不限,最后取光者得胜。

        这 种情况最有意思,它与二进制有密切关系,我们用(a,b,c)表示某种局势,首先(0,0,0)显然是奇异局势,无论谁面对奇异局势,都必然失败。第二种 奇异局势是(0,n,n),只要与对手拿走一样多的物品,最后都将导致(0,0,0)。仔细分析一下,(1,2,3)也是奇异局势,无论对手如何拿,接下 来都可以变为(0,n,n)的情形。

        计算机算法里面有一种叫做按位模2加,也叫做异或的运算,我们用符号(+)表示这种运算。这种运算和一般加法不同的一点是1+1=0。先看(1,2,3)的按位模2加的结果:

    1 =二进制01
    2 =二进制10
    3 =二进制11 (+)
    ———————
    0 =二进制00 (注意不进位)

        对于奇异局势(0,n,n)也一样,结果也是0。

        任何奇异局势(a,b,c)都有a(+)b(+)c =0。

    如 果我们面对的是一个非奇异局势(a,b,c),要如何变为奇异局势呢?假设 a < b< c,我们只要将 c 变为 a(+)b,即可,因为有如下的运算结果: a(+)b(+)(a(+)b)=(a(+)a)(+)(b(+)b)=0(+)0=0。要将c 变为a(+)b,只要从 c中减去 c-(a(+)b)即可。

    获胜情况对先取者进行讨论:

    异或结果为0,先取者必败,无获胜方法。后取者获胜;

    结果不为0,先取者有获胜的取法。

     拓展: 任给N堆石子,两人轮流从任一堆中任取(每次只能取自一堆),取最后一颗石子的人获胜,问先取的人如何获胜?

    根据上面所述,N个数异或即可。如果开始的时候T=0,那么先取者必败,如果开始的时候T>0,那么只要每次取出石子使得T=0,即先取者有获胜的方法。

     

     【综合一、三给出】

    任给N堆石子,两人轮流从任一堆中任取(每次只能取自一堆),规定每方每次最多取K颗,取最后一颗石子的一方获胜.问先取的人如何获胜?

    与上面的问题比,这个更复杂一些,我们可以这样做

    令Bi=Ai mod(K+1)

    定义T‘=B1 xor B2 xor ... xor Bn

    如果T‘=0 那么没有获胜可能,先取者必败

    如果T’>0 那么必然存在取的方法,使得T‘=0,先取者有获胜的方法

    假设对方取了在Ai中取了r<=K个

    如果Ai中剩下的石子多于K 那么就在Ai中取走K+1-r个则Bi不变 T‘还是0

    如果Ai<=K 那么我们需要重新计算Bi和T‘ 按照上面的方法来做就可以了

     

    下面对wythoff博弈真的讲的超详细~~

    【补】EP6: Wythoff’s Game (威佐夫博弈)

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://yjq24.blogbus.com/logs/42826226.html

    大致上是这样的:有两堆石子,不妨先认为一堆有10,另一堆有15个,双方轮流取走一些石子,合法的取法有如下两种:

    1)在一堆石子中取走任意多颗;

    2)在两堆石子中取走相同多的任意颗;

    约定取走最后一颗石子的人为赢家,求必败态(必胜策略)。

    这个可以说是MR.Wythoff(Wythoff于1907年提出此游戏)一生全部的贡献吧,我在一篇日志里就说完有点残酷。这个问题好像被用作编程竞赛的题目,网上有很多把它Label为POJ1067,不过如果学编程的人不知道Beatty定理和Beatty序列 ,他们所做的只能是找规律而已。不熟悉的人可以先在这里 玩几局~

    简单分析一下,容易知道两堆石头地位是一样的,我们用余下的石子数(a,b)来表示状态,并画在平面直角坐标系上。

    用之前的定理: 有限个结点的无回路有向图有唯一的核  中 所述的方法寻找必败态。先标出(0,0),然后划去所有(0,k),(k,0),(k,k)的格点;然后找y=x上方未被划去的格点,标出(1,2),然 后划去(1,k),(k,2),(1+k,2+k),同时标出对称点(2,1),划去(2,k),(1,k),(2+k,1+k);然后在未被划去的点中 在y=x上方再找出(3,5)。。。按照这样的方法做下去,如果只列出a<=b的必败态的话,前面的一些是(0,0),(1,2),(3,5), (4,7),(6,10),…

    接下来就是找规律的过程了,忽略(0,0),记第n组必败态为(a[n],b[n])

    命题一:a[n+1]=前n组必败态中未出现过的最小正整数

    [分析]:如果a[n+1]不是未出现的数中最小的,那么可以从a[n+1]的状态走到一个使a[n+1]更小的状态,和我们的寻找方法矛盾。

    命题二:b[n]=a[n]+n

    [分析]:归纳法:若前k个必败态分别为 ,下证:第k+1个必败态为

    从该第k+1个必败态出发,一共可能走向三类状态,从左边堆拿走一些,从右边堆拿走一些,或者从两堆中拿走一些.下面证明这三类都是胜态.

    情况一:由命题一,任意一个比a[k+1]小的数都在之前的必败态中出现过,一旦把左边堆拿少了,我们只要再拿成那个数相应的必败态即可。

    情况二(从右边堆拿走不太多):这使得两堆之间的差变小了,比如拿成了 ,则可再拿成 ;

    情况二(从右边堆拿走很多):使得右边一堆比左边一堆更少,这时类似于情况一,比如拿成了 (其中a[m] ;

    情况三:比如拿成 ,则可再拿成 .

    综上所述,任何从 出发走向的状态都可以走回核中.故原命题成立.

    以上两个命题对于确定(a[n],b[n])是完备的了,给定(0,0)然后按照这两个命题,就可以写出(1,2),(3,5),(4,7),…

    这样我们得到了这个数列的递推式,以下我们把这两个命题当成是(a[n],b[n])的定义。

    先证明两个性质:

    性质一:核中的a[n],b[n]遍历所有正整数。

    [分析]:由命题一,二可得a[n],b[n]是递增的,且由a[n]的定义显然。

    性质二:A={a[n]:n=1,2,3,…},B={b[n]:n=1,2,3,…},则集合A,B不交。

    [分析]:由核是内固集,显然。

    看到这里大家有没有想到Beatty序列呢,实际上a[n]和b[n]就是一个Beatty序列。

     ,有  ,解方程 

      ,到此,我们找到了该必败态的通项公式。

    实际上这组Beatty序列还有一些别的性质,比如当一个数是Fibonacci数的时候,另一个数也是Fibonacci数;而且两者的比值也越来越接近黄金比,这些性质在得到通项公式之后不难证明。

    总的来说,这个问题给我们了哪些启示呢?首先用定理所说的方法找核,然后给出核的规律(递推,或是通项)并且证明。最后附上一张对应的必败态图.

    wythoff

  • 相关阅读:
    git操作
    计算天数
    web小结~2019.3.24
    数据统计值的计算+PYTHON
    python~序列类型及操作
    一个日期加上若干天后是什么日期
    完数与盈数
    分段函数
    求最大最小
    D进制的A+B
  • 原文地址:https://www.cnblogs.com/Tunix/p/4297944.html
Copyright © 2011-2022 走看看