zoukankan      html  css  js  c++  java
  • 组合游戏与博弈

    【引言】

      分金币问题:有100个金币,两个人轮流从这堆金币中取金币,规定每次至少取1个,最多取5个。取完最后一枚金币的人获胜。假入你先手取金币,对方是足够聪明的,你能找到一种必胜的方法吗?

    【问题分析】

      首先我们考虑到这样一个简单的事实,如果最后把6个金币留给对方去取,那么很显然,对方必败。再往前推进一步,如果把12枚金币留给对方去取,对方也必败。

      为什么呢?原因很简单,不论对方取几个,我都能够把金币取成6个,这样就回到上一个对方必败的局势了。

      那么我们可以更进一步地推出,如果把金币取成18个,24个,30个.......留个对方呢?我们都可以必胜。所以可以推出,如果一开始金币不是6的倍数,我们必然可以将其取成6的倍数,对方必败。

      反过来考虑,如果一开始金币就是6的倍数,我们先手又不得不取,那么不论我们取几个,对方一定会将其取成6的倍数,那么我们先手必败。至此可以得出这样一个结论:初始金币个数100不是(5+1)的倍数,先手必胜。

    【问题推广】如果金币是N个,每次至多取M个,至少取一个,那么先手胜负情况如何?

    结论:当 N %(M+1)= 0时,先手必败,否则,先手必胜。这样对于这个问题,我们就总结出了一般性规律,这个游戏很经典,我们称之为--巴什博弈。

    【理论上升】我们已经总结出了巴什博弈的一般性规律,那么对于诸于此类的组合游戏,我们如何去用更抽象的工具去研究它呢?

    引入P点和N点,

       P点: 即必败点,某玩家位于此点,只要对方无失误,则必败;

       N点: 即必胜点,某玩家位于此点,只要自己无失误,则必胜。

    P/N点有如下性质:

    (1)P点不能一步到达下一个P点,N点可以一步到达P点。这就是为什么面临P点必败,因为你只要到达了P点,再进行决策无法再使局面变为P点,这样的话必然把N点留给对方,对方面临N点,又能一步到达P点,又将P点(必败点)留给了你,这样下去你必败无疑。

    (2)终结状态是P点。很好理解,当上一个人把所有金币取完了,那么这时的状态变成P点,你面临的是空空如也,是胜负已分的终结状态,所以终结状态是P点。

    (3)决定先手是否必胜,只要看初始局势是P点还是N点。是P点,必败;是N点,必胜。

    在引言的取金币问题中,当n = 19, m = 5时, P/N状态如下表。显然,初始状态,剩余19个,是N点,先手必胜。

    【问题推广和变形】

    一、巴什博弈

    1、问题模型:只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个,最后取光者得胜。

    2、解决思路:当n=m+1时,由于一次最多只能取m个,所以无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜,所以当一方面对的局势是n%(m+1)=0时,其面临的是必败的局势。所以当n=(m+1)*r+s,(r为任意自然数,s≤m)时,如果先取者要拿走s个物品,如果后取者拿走x(≤m)个,那么先取者再拿走m+1-k个,结果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜。总之,要保持给对手留下(m+1)的倍数,就能最后获胜。

    3.一般性规律:当 N %(M+1)= 0时,先手必败,否则,先手必胜。

    二、威佐夫博弈

    1.问题模型:有两堆物品,数量分别为M,N,两个人轮流取物品,先取完所有物品的人获胜。取物品时有两种方法,一是可以从某一堆取若干物品(至少一个,多者不限),或者是从两堆中同时取相同数量的物品。

    2.策略:首先我们考虑一下面临什么局势会输,也就是两堆物品数量分别是什么的时候会输,也就是什么是P点。

    (1)显然(0,0)是P点。然后(1,2)是P点,为什么呢,因为有个2在,不论你在第一堆取还是第二堆取,剩下的人一定可以取完所有。进一步思考,当你面临(2,x),其中x>=2,你必胜,因为你要么一次性取完所有,要么把(1,2)留给对手,对手必败。所以除了(2,1),其他所有(2,x)都不是必败点。

    (2)考虑(3,x)必败的情况,(3,1)(3,2)(3,3)显然都是必胜点。进一步推知(3,4)是必胜点。然后我们试试(3,5),发现它是必败点。你不论怎么取都会把之前我们已知的必胜点留给对方,所以你必败。x>5的情况呢,必然是必胜点,因为你可以把X取成5,把必败点(3,5)留给对方。这样我们可以得出结论(3,x)中除了(3,5)必败其余都是必胜。

    (3)考虑(4,x)必败的情况,(4,1)(4,2)(4,3)(4,5),(4,6)显然都是必胜点。然而(4,7)却是必败点,你不论怎么取都会把之前我们已知的必胜点留给对方,所以你必败。

    (4)这样我们已经知道的必败局势有(0,0)、(1,2)、(3,5)、(4,7),我们把这种局势称之为奇异局势。不难发现,如果记(ak, bk)为第k个奇异局势(第0个必败局势是(0,0)),那么ak是之前未出现过的最小数字,bk = ak + k;

    3.一般性规律

    那么第K项的(ak, bk)是什么呢?通项公式是:

    具体证明见:https://baike.baidu.com/item/%E5%A8%81%E4%BD%90%E5%A4%AB%E5%8D%9A%E5%BC%88/19858256?fr=aladdin

     4.注意事项。由于ak是整数,所以k一旦很大,比如10^100对根号5的精度要求极高,这时候调用库函数sqrt(double x)是得不到这么高的精度的,需要自己去实现一个实数开方的方法,返回一个高精度实数。

    具体可以见我的另外一篇博客

    三、尼姆博弈

    1. 问题模型:有3堆各若干个物品,两个人轮流从某一堆取任意多的物品,每次至少取一个,多者不限,最后取光者得胜。

    2. 策略:

    (1)首先我们分分析一下奇异局势。(0,0,0)是第一个奇异局势,然后可以证明(0,n,  n)是奇异局势,因为只要把这个局势留给对面,对面在一堆中取几个,那么我们都在另外一堆取相同数目的物品,到最后肯定胜利。

    (2)如果面临的局势是(1,2,3),你可以发现这也是一个奇异局势,因为无论怎么取,对手必然可以将其变为(0,n,  n)的局势留给你。

    如果面临(5,6,3),我们把它写成二进制阵列的形式:

     1 0 1

     1 1 0

     0 1 1

    可以发现,不论你取走哪一行的哪一个1,我都取走另外某一行的对应位的1,并且最后一定是我(后手)胜利。

    进一步可以发现,这三个数的二进制阵列中,第1列到最后一列都有偶数个1,所以我们可以采取前面所说的策略,不论先手取走哪一行的哪一列的一个1,我都取走另外某一行的对应列的一个1。这样必然能够使得我取走该矩阵该列最后一个1,如果对于该矩阵每一列我能取走最后一个1,那么很显然,我必然是先取光所有物品的人。

    由此我们可以发现:只要把这三个数写成二进制矩阵的形式,看看该矩阵是不是每一列的1的数目都是偶数,如果是,先手必败。

    这样的矩阵有什么特点呢?那就是二进制的异或和为0.(每一列1的个数都是偶数嘛)。如果局势(x,y,z)是奇异局势,那么x xor y xor z = 0.

    3. 推广到N堆,局势(X1, X2 , X3, X4, ......Xn)为奇异局势的充要条件是 X1 xor X2 xor  X3 xor  X4 xor  ......xor  Xn  =   0.

    四、斐波那契博弈(引用自大佬博客

    1、问题模型:

     有一堆个数为n的石子,游戏双方轮流取石子,满足: 

    (1)先手不能在第一次把所有的石子取完; 

    (2)之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间(包含1和对手刚取的石子数的2倍)。 约定取走最后一个石子的人为赢家。

    2、策略:

      当n为Fibonacci数时,先手必败。即存在先手的必败态当且仅当石头个数为Fibonacci数。 

        证明:根据“Zeckendorf定理”(齐肯多夫定理):任何正整数可以表示为若干个不连续的Fibonacci数之和。如n=83 = 55+21+5+2,我们看看这个分解有什么指导意义:假如先手取2颗,那么后手无法取5颗或更多,而5是一个Fibonacci数,那么一定是先手取走这5颗石子中的最后一颗,同理,接下去先手取走接下来的后21颗中的最后一颗,再取走后55颗中的最后一颗,那么先手赢。

        反证:如果n是Fibonacci数,如n=89:记先手一开始所取的石子数为y

        (1)若y>=34颗(也就是89的向前两项),那么一定后手赢,因为89-34=55=34+21<2*34。

        (2)y<34时剩下的石子数x介于55到89之间,它一定不是一个Fibonacci数,把x分解成Fibonacci数:x=55+f[i]+…+f[j],若,如果f[j]<=2y,那么对B就是面临x局面的先手,所以根据之前的分析,后手只要先取f[j]个即可,以后再按之前的分析就可保证必胜。

    五、公平组合游戏与SG函数(未完待续)

  • 相关阅读:
    java Class的 getSuperclass与getGenericSuperclass区别
    再有人问你volatile是什么,把这篇文章也发给他
    深入理解乐观锁与悲观锁
    再有人问你Java内存模型是什么,就把这篇文章发给他
    再有人问你synchronized是什么,就把这篇文章发给他
    《成神之路-基础篇》JVM——Java内存模型(已完结)
    css
    css
    require.js
    css -border
  • 原文地址:https://www.cnblogs.com/czsharecode/p/9627401.html
Copyright © 2011-2022 走看看