zoukankan      html  css  js  c++  java
  • 经典数学问题:Nim游戏

    Nim游戏的数学理论论述

    Nim游戏是博弈论中最经典的模型,是组合游戏(Combinatorial Games)的一种,属于“Impartial Combinatorial Games”(以下简称ICG)。

    满足以下条件的游戏是ICG:
    1、有两名选手;
    2、两名选手交替对游戏进行移动(move),每次一步,选手可以在(一般而言)有限的合法移动集合中任选一种进行移动;
    3、对于游戏的任何一种可能的局面,合法的移动集合只取决于这个局面本身,不取决于轮到哪名选手操作、以前的任何操作、骰子的点数或者其它什么因素;
    4、如果轮到某名选手移动,且这个局面的合法的移动集合为空(也就是说此时无法进行移动),则这名选手负。

    通常的Nim游戏的定义是这样的:有若干堆石子,每堆石子的数量都是有限的,合法的移动是“选择一堆石子并拿走若干颗(不能不拿)”,如果轮到某个人时所有的石子堆都已经被拿空了,则判负(因为他此刻没有任何合法的移动)。

    分析

    从简单情况开始研究

    如果轮到你的时候,只剩下一堆石子,那么此时的必胜策略肯定是把这堆石子全部拿完一颗也不给对手剩,然后对手就输了。

    如果剩下两堆不相等的石子,必胜策略是通过取多的一堆的石子将两堆石子变得相等,以后如果对手在某一堆里拿若干颗,你就可以在另一堆中拿同样多的颗数,直至胜利。

    如果你面对的是两堆相等的石子,那么此时你是没有任何必胜策略的,反而对手可以遵循上面的策略保证必胜。

    深入研究

    定义P-position和N-position,其中P代表Previous,N代表Next。

    直观的说,上一次move的人有必胜策略的局面是P-position,也就是“后手可保证必胜”或者“先手必败”,现在轮到move的人有必胜策略的局面是N-position,也就是“先手可保证必胜”。

    更严谨的定义是:
    1.无法进行任何移动的局面(也就是terminal position)是P-position;
    2.可以移动到P-position的局面是N-position;
    3.所有移动都导致N-position的局面是P-position。

    按照这个定义,如果局面不可能重现,或者说positions的集合可以进行拓扑排序,那么每个position或者是P-position或者是N-position,而且可以通过定义计算出来。

    比如刚才说的当只有两堆石子且两堆石子数量相等时后手有必胜策略,也就是这是一个P-position,下面依靠定义证明一下(3,3)P-position。

    首先(3,3)的子局面有(0,3)(1,3)(2,3),只需要计算出这三种局面的性质就可以了。

    (0,3)的子局面有(0,0)、(0,1)、(0,2),其中(0,0)显然是P-position,所以(0,3)是N-position(只要找到一个是P-position的子局面就能说明是N-position)。
    (1,3)的后继中(1,1)是P-position(因为(1,1)的唯一子局面(0,1)是N-position),所以(1,3)也是N-position。
    同样可以证明(2,3)是N-position。
    所以(3,3)的所有子局面都是N-position,它就是P-position。
    通过一点简单的数学归纳,可以严格的证明“有两堆石子时的局面是P-position当且仅当这两堆石子的数目相等”。

    根据上面这个过程,可以得到一个递归的算法——对于当前的局面,递归计算它的所有子局面的性质,如果存在某个子局面是P-position,那么向这个子局面的移动就是必胜策略。

    当然,有大量的重叠子问题,所以可以用DP或者记忆化搜索的方法以提高效率。

    但问题是,利用这个算法,对于某个Nim游戏的局面(a1,a2,…,an)来说,要想判断它的性质以及找出必胜策略,需要计算O(a1a2…*an)个局面的性质,不管怎样记忆化都无法降低这个时间复杂度。

    所以我们需要更高效的判断Nim游戏的局面的性质的方法。

    (Bouton’s Theorem):对于一个Nim游戏的局面(a1,a2,…,an),它是P-position当且仅当a1a2an=0,其中表示异或(xor)运算。

    证明

    证明一种判断position的性质的方法的正确性,只需证明三个命题:
    1、这个判断将所有terminal position判为P-position;
    2、根据这个判断被判为N-position的局面一定可以移动到某个P-position;
    3、根据这个判断被判为P-position的局面无法移动到某个P-position。

    第一个命题显然,terminal position只有一个,就是全0,异或仍然是0。

    第二个命题,对于某个局面(a1,a2,…,an),若a1^ a2^ …^ an!=0,一定存在某个合法的移动,将ai改变成ai’后满足a1^ a2^ …^ ai’^ …^ an=0。不妨设a1^ a2^ …^ an=k,则一定存在某个ai,它的二进制表示在k的最高位上是1(否则k的最高位那个1是怎么得到的)。这时ai^ k<ai一定成立。则我们可以将ai改变成ai’=ai^ k,此时a1^ a2^ …^ ai’^ …^ an=a1^ a2^ …^ an^ k=0。

    第三个命题,对于某个局面(a1,a2,…,an),若a1^ a2^ …^ an=0,一定不存在某个合法的移动,将ai改变成ai’后满足a1^ a2^ …^ ai’^ …^ an=0。因为异或运算满足消去率,由a1^ a2^ …^ an=a1^ a2^ …^ ai’^ …^ an可以得到ai=ai’。所以将ai改变成ai’不是一个合法的移动。证毕。

    根据这个定理,我们可以在O(n)的时间内判断一个Nim的局面的性质,且如果它是N-position,也可以在O(n)的时间内找到所有的必胜策略。Nim问题就这样基本上完美的解决了。

    Nim游戏的形象具体论述:

    Nim取子游戏是由两个人面对若干堆硬币(或石子)进行的游戏。
    设有k>=1堆硬币,各堆分别含有N1,N2,……NK枚硬币。
    游戏的目的就是选择最后剩下的硬币。
    游戏法则如下:
    1.两个游戏人交替进行游戏(游戏人I和游戏人II);
    2.当轮到每个游戏人取子时,选择这些堆中的一堆,并从所选的堆中取走至少一枚硬币(游戏人可以取走他所选堆中的全部硬币);
    3.当所有的堆都变成空堆时,最后取子的游戏人即为胜者。
    这个游戏中的变量是堆数k和各堆的硬币数N1,N2,……Nk。对应的组合问题是,确定游戏人I获胜还是游戏人II获胜以及两个游戏人应该如何取子才能保证自己获胜(获胜策略)。

    思路

    首选考查某些特殊情况。

    如果游戏开始时只有一堆硬币,游戏人I则通过取走所有的硬币而获胜。

    现在设有2堆硬币,且硬币数量分别为N1和N2,游戏人取得胜利取决于它们是否相等。
    设N1!=N2,游戏人I从大堆中取走的硬币使得两堆硬币数量相等,于是,游戏人I以后每次取子的数量与游戏人II相等而最终获胜。
    但是如果N1= N2,则:游戏人II只要按着游戏人I取子的数量在另一堆中取相等数量的硬币,最终获胜者将会是游戏人II。
    这样,两堆的取子获胜策略就已经找到了。

    每个正整数都有对应的一个二进制数,例如:57(10) =111001(2) ,即:57(10)=25+24+23+20
    于是,我们可以认为每一堆硬币数由2的幂数的子堆组成。
    这样,含有57枚硬币大堆就能看成是分别由数量为25、24、23、20的各个子堆组成。
    现在考虑各大堆大小分别为N1,N2,……Nk的一般的Nim取子游戏。
    将每一个数Ni表示为其二进制数(数的位数相等,不等时在前面补0):
    N1 = as…a1a0
    N2 = bs…b1b0
    ……
    Nk = ms…m1m0
    如果每一种大小的子堆的个数都是偶数,我们就称Nim取子游戏是平衡的,而对应位相加是偶数的称为平衡位,否则称为非平衡位。
    因此,Nim取子游戏是平衡的,当且仅当:
    as + bs + … + ms 是偶数
    ……
    a1 + b1 + … + m1 是偶数
    a0 + b0 + … + m0是偶数

    于是,我们就能得出获胜策略:
    游戏人I能够在非平衡取子游戏中取胜,而游戏人II能够在平衡的取子游戏中取胜。

  • 相关阅读:
    黑马程序员————C语言基础语法二(算数运算、赋值运算符、自增自减、sizeof、关系运算、逻辑运算、三目运算符、选择结构、循环结构)
    django启动前的安装
    React的条件渲染和列表渲染
    React学习第二天
    go语言切片
    mongodb
    Flask路由层
    Flask基础简介
    celery介绍及django使用方法
    redis的介绍及django使用redis
  • 原文地址:https://www.cnblogs.com/AlexKing007/p/12338421.html
Copyright © 2011-2022 走看看