三种基本博弈以及SG函数、定理

4 篇文章 0 订阅
2 篇文章 0 订阅

先开个坑 简单写下公式,推导(不一定会写)和拓展应用慢慢补充
1.三种博弈
1.1.巴什博弈
简介:n个物品 双方每次取x个(1<=x<=k),最后一个取得物品的人获胜。
最优策略:

如果n%(k+1)=0的时候先手必败
否则先手先取 n%(k+1) 随后与对手所取的物品量的和维持(k+1)就可获胜。

1.2.威佐夫博弈(维基)

简介:有两堆物品。两方轮流从一堆或两堆中拿走物品。在拿物品时有两种方法:其一是从两堆拿走相同量的物品;其二是从其中一堆拿走任意量的物品。
最后一个取得物品的人获胜。

最优策略:

游戏过程中的任何状态都可用一对正整数(n,m)来表示,其中n≤m,分别表示两堆筹码的数目。所有状态分为两种:先手必胜和后手必胜。在双方均采取最佳策略的情况下,前者表示下一个行动的玩家将取胜,后者表示下一个行动的玩家将落败。可见,游戏的最佳策略是从一个先手必胜状态移动到任一后手必胜状态。


对于任一状态(n,m),可用以下法则递归地判断此状态是先手必胜还是后手必胜:

   1.(0,0)为后手必胜状态。
   2.若一个状态的后续中存在后手必胜状态,则该状态为先手必胜。 
   3.若一个状态的全部后续均为先手必胜,则该状态为后手必胜。

例如,由上述第一条、第二条可推出对所有的正整数m,(0,m)和(m,m)均为先手必胜状态。
而(1,2)是后手必胜状态,因为它的后续(0,1)、(0,2)和(1,1)均为先手必胜状态。
前几个后手必胜状态为(0,0)、(1, 2)、(3, 5)、(4, 7)、(6,10)和(8, 13)。


上图是威佐夫游戏中的后手必胜状态。以左下角为原点向右、上为正方向建立坐标系,以红色标出的小正方形右上角的顶点坐标即为后手必胜状态(看看就行)


最优策略
后手胜利时,设横坐标n纵坐标m,形成的序列为N和M 通项公式如下:
在这里插入图片描述
在这里插入图片描述
在OEIS上的这两个序列NM
黄金分割的值Φ= (1+sqrt(5))/2

phi=(1+sqrt(5))/2

1.3 NIM博弈(维基)
简介:
游戏者轮流从几排棋子(或者任何道具)中选择一排,再由这一排中取走一个或者多个,依规则不同,拿走最后一个的可能是输家,也有可能是赢家。当指定相应数量时,一堆这样的棋子称作一个尼姆堆.
如下是当有3排棋子 数量分别为3 4 5时的一种游戏情况
在这里插入图片描述
a.当拿走最后一个棋子胜利时(normal版本):
如果所有堆中的异或和为0 ,后手胜利
否则先手胜利
期望最后一排剩下偶数个
b.当拿走最后一个棋子失败时(misère版本):
其他的策略一致,期望最后一排剩下奇数个
如果异或和为0,后手胜利
2.SG函数
SG(x)=MEX{f(y)|y时x的后继}

a.dfs

//注意 S数组要按从小到大排序 SG函数要初始化为-1 对于每个集合只需初始化1遍
//n是集合s的大小 S[i]是定义的特殊取法规则的数组
int s[110],sg[10010],n;
int SG_dfs(int x)
{
    int i;
    if(sg[x]!=-1)
        return sg[x];
    bool vis[110];
    memset(vis,0,sizeof(vis));
    for(i=0;i<n;i++)
    {
        if(x>=s[i])
        {
            SG_dfs(x-s[i]);
            vis[sg[x-s[i]]]=1;
        }
    }
    int e;
    for(i=0;;i++)
        if(!vis[i])
        {
            e=i;
            break;
        }
    return sg[x]=e;
}

b.顺序检索

//f[]:可以取走的石子个数
//sg[]:0~n的SG函数值
//hash[]:mex{}
int f[N],sg[N],hash[N];     
void getSG(int n)
{
    int i,j;
    memset(sg,0,sizeof(sg));
    for(i=1;i<=n;i++)
    {
        memset(hash,0,sizeof(hash));
        for(j=1;f[j]<=i;j++)
            hash[sg[i-f[j]]]=1;
        for(j=0;j<=n;j++)    //求mes{}中未出现的最小的非负整数
        {
            if(hash[j]==0)
            {
                sg[i]=j;
                break;
            }
        }
    }
}

SG定理
sg(X) = sg(x[1]) ^ sg(x[2]) ^ … ^ sg(x[n])

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值