码迷,mamicode.com
首页 > 其他好文 > 详细

博弈论入门

时间:2019-02-26 19:06:23      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:有一个   完成   证明   转化   威佐夫博弈   怎么   []   imm   flag   

博弈论入门

博弈

巴什博弈 Bash Game

模型

只有一堆n个物品,两个人从轮流中取出(1~m)个;最后取光者胜。

思路

考虑到 若n=m+1 那么 第一个人不论如何取都不能取胜。

进一步我们发现 若 n=k*(m+1)+r; 先取者拿走 r 个,那么后者再拿(1~m)个

n=(k-1)*(m+1)+s; 先取者再拿走s 个 最后总能造成 剩下n=m+1 的局面。

因此,此时先手有必赢策略。相对应的,若n=k*(m+1) 那么先取者必输。

因此我们就可以写出对应程序(n,m>0)

int Bash_Game(int n,int m)//是否先手有必赢策略
{
    if (n%(m+1)!=0) return 1;
    return 0;
}

尼姆博弈 Nim Game

模型

当前有n堆每堆\(M_i>0\)个物品,两个人从轮流中取出若干个;最后取光者胜。

思路

从Bash Game中我们知道一个情形对应的一种状态,而从一个状态只能变成另一个状态时能很轻易的判定是否先手必胜

那么我们怎么把这样一个思想应用到Nim中呢

换句话说怎样才能在Nim中找到这样一个可以转化的状态

如果我们把n堆转化为n个整数,再将这n个整数用二进制表示,然后我们对这n个二进制数按位相加(不进位),若每一位相加都为偶数

那么我们称这个状态为偶状态,否则为奇状态;

可以证明:任何一个偶状态在其中一个数变小后一定会成为奇状态,一个奇状态一点可以通过改变一个数变为偶状态;

前一点很显然,因为一个数变小至少有一位发生变化,那么这一位就会改变原来的偶状态;

对于后一点,我们考虑一个从高位到低位某一位和为奇数的奇状态,必然有一个数的二进制此位为1,那么对于后面的较低位和为奇数的情况,只需要将这一位取反就可以得到一个偶状态;

那么现在我们就达到了成功的第一步——构造两个可以互相转化的状态并且显然存在奇状态为必胜态;偶状态为必败态;

那么我们对于n堆物品只需要判断他是否为奇状态就可以判定是否先手必胜;

但是对于每个数都二进制拆分非常麻烦,但是我们可以用神奇的位运算来完成这个过程

神奇的XOR与判断

如果有奇数个二进制数在第k为等于1那么显然在这一位上的和为奇数,同样的若有偶数个1则和为偶。

很明显位运算XOR满足我们的要求,偶数个1异或和为0,奇数个1异或和为1;

美滋滋这样不就搞完了

int Nimm_Game(int n)//假设n个数存在数组f[]中,有必胜策略返回1
{
    int flag=0;
    for(int i=1;i<=n;i++)
    flag^=f[i];
    if(flag) return 1;
    return 0;
}

一些小情况

但是当你遇到n非常大,并且每一堆的物品数是连续的整数的时候

我们就不能直接枚举n了

我们需要考虑连续非负整数的异或和问题

\(f(x,y)\)\(x\)\(y\)的所有整数的异或和。

f[1,n]=f[0,n];

当存在\(n=2^k-1\)\(,f(1,n)=f(0,n)=0,(k\geq2)\)

证明:

我们先来考虑\(f(2^k,2^{k+1}-1)\)

\(2^k\)\(2^{k+1}-1\)\(2^k\)个数,最高位的一个数为\(2^k\)

若有\(k>=1\),则\(2^k\)为偶数,将这\(2^k\)个数的最高位去掉,异或和不变

因此\(f(2^k,2^{k+1}-1)=f(2^k-2^k,2^{k+1}-2^k-1)=f(0,2^{k}-1)\)

因而存在\(f(0,2^{k+1}-1)=f(0,2^k-1) xor f(2^k,2^{k+1}-1)=0\)

\(f(0,2^k-1)=0\)

对于\(,f(0,n),n\geq4\)设n二进制表示的最高位1在第k位k>=2;

\(f(0,n)=f(0,2^k-1) xor f(2^k,n)=f(2^k,n)\)

对于\(2^k\)\(n\)\(n-2^k+1\)个数,最高位共有\(m=n-2^k+1\)个1,去除最高位的1

当n为奇数时,m为偶数此时有\(f(0,n)=f(2^k,n)=f(0,n-2^k)|2^k\)

由于\(n-2^k\)与n奇偶性相同,递推上面的公式可得\(f(0,n)=f(0,n-2^k-2^{k-1}-2^{k-2}\cdots -2^2)=f(0,n\%4)\)

\(n\%4=1\)\(f(0,n)=f(0,1)=1\)

\(n\%4=3\)\(f(0,n)=f(0,3)=0\)

当n为偶数时,m为奇数,因而\(f(0,n)=f(2^k,n)=f(0,n-2^k)xor2^k\)

也相当于最高位不变,递推公式可得

\(f(0,n)=f(0,n\%4)xor 2^kxor\) \(n[k]*2^k-1 xor\cdots\) \(n[2]*2^2\)

n[k]表示n的二进制表示的第k位

显然当n为偶数时 \(f(0,n)\)的二进制从最高位到第3位和n的二进制表示相同

此时我们只需要判断第二位

\(n\%4=0\)\(f(0,n)=n\)

\(n\%4=2\)\(f(0,n)=n+1\)

综上所述:

\[f(0,n)=f(1,n)\begin{cases} n\ \ \ \ \ \ \ \quad n\%4=0\1\ \ \ \ \ \ \ \quad n\%4=1\\n+1 \quad n\%4=2\\0\ \ \ \ \ \ \ \quad n\%4=3\\end{cases}\]

代码给出来吧

//读入n,表示有从物品数分别1到n的n组物品,假设n个数存在数组f[]中
int xor_n(int n)//从1到n的异或和
{
     int t = n & 3;
     if (t & 1) return t / 2 ^ 1;
     return t / 2 ^ n;
}
int Nimm_Game(int n)//有必胜策略返回1
{
    int flag=0;
    for(int i=1;i<=n;i++)
    flag^=xor_n(f[i]);
    if(flag) return 1;
    return 0;
}

新Nim Game

在第一个回合中,第一个游戏者可以直接拿走若干个整堆的火柴。可以一堆都不拿,但不可以全部拿走。第二回合也一样,第二个游戏者也有这样一次机会。从第三个回合(又轮到第一个游戏者)开始,规则和Nim游戏一样。

如果你先拿,怎样才能保证获胜?如果可以获胜的话,还要让第一回合拿的火柴总数尽量小。

题解

我们第一次拿完后,要使得剩下的火柴中不存在异或和为0的子集,否则对方会将先手必败的状态留给我们。

所以我们可以使用贪心算法确定最优解。因此我们采用在线维护线性基的方法判断当前的数能否加入集合。


威佐夫博弈 Wythoff Game

模型

有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。

思路

博弈论入门

标签:有一个   完成   证明   转化   威佐夫博弈   怎么   []   imm   flag   

原文地址:https://www.cnblogs.com/My-snowing/p/10439231.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!