• 【数论】(浅)博弈论学习笔记


    两周前去学nim和sg函数,但是,又又又忘了QAQ

     一,nim博弈

    0,对nim游戏的定义是:两人,有若干堆石子,每堆石子数量是有限的(a1,a2,...,an),合法的移动时候:选择一堆石子并拿走若干颗(可以全拿,不能不拿)。如果轮到某人时,已无子可取,则为败,另一人为胜。

    1,设P-position为先手必败(当前态为必败态)/后手可保证必胜;

    2,设N-position先手可保证必胜(当前态为必胜态);

    3,设游戏中无法进行任何移动的局面(terminal position)为P-position;

    4,可以移动到P-position的局面是N-position(性质);

    5,所有移动都导致N-position的局面是P-position(性质);

    6,对nim有结论:对于一个nim游戏的局面(a1,a2,...,an),它是P-position当且仅当a1^a2^...^an==0(即,a1^a2^...^an!=0 为N-position);

    7,判断6的正确性:

      (1),对于terminal position,a1=a2=...=an=0,有a1^a2^...^an=0,而对于定义terminal potion为P-position,成立。

      (2),假设6成立,则需满足N-position一定能移动到P-position(第4点),

          N-position为 a1^a2^...^an!=0 ,设 a1^a2^...^an!=k (k!=0),则一定存在某个ai,它的二进制表示的最高位1为k而进制表示的最高位1,在这时,当前 将ai(通过取石子)的值,变换为ai`=ai^k,则有:a1^a2^...^an^k=k^k=0,在假设6成立下性质满足。

      (3),假设6成立,则需满足P-position一定无法使下一个状态为P-position(第5点),

          P-position为 a1^a2^...^ai^...^an==0 ,则,显然 a1^a2^...^ai`^...^an!=0(ai`<ai)。

      所以6的正确性显然。

    8,进一步,假设nim游戏有:每次最多只能取k个,的限制,则:将每堆石子数mod(k+1);。

    9,SG函数:Sprague-Grundy函数:详见这个博客

      首先定义mex(局外最小序数)运算,对于一个集合S,mex(S)为,不是S的元素的最小一个序数(非负)。如:mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。

      给定一个有向无环图和一个起始顶点上的一枚棋子,两名选手交替的将这枚棋子沿有向边进行移动,无法移动者判负。

      对于一个给定的有向无环图,定义关于图的每个顶点的Sprague-Garundy函数g:g(x)=mex{ g(y) | y是x的后继 }。

      且定义:(1)叶子节点(terminal potsition)的SG值为0。

       则有:(2)对于一个g(x)==0的顶点x,它的所有后继y都满足g(y)!=0。

          (3)对于一个g(x)!=0的顶点x,它必有一个后继y满足g(y)==0。

      则,由上面3点,可知,顶点x所代表的position为P-position当且仅当g(x)==0(即,g(x)!=0为N-position)

      详见博客= =

      当面对由n个游戏组合成的一个游戏时,只需对于每个游戏找出它每个局面的SG值的方法,就可以把SG值全部看出nim的石子堆,再由nim的必胜策略判断必胜局面。

      SG值根据mex函数确定,具体方法为打表orDFS。

    10,原文链接:https://blog.csdn.net/strangedbly/article/details/51137432

      解题模型

      (1)把原游戏分解成多个独立的子游戏,则原游戏的SG函数值是它的所有子游戏的SG函数值的异或。即sg(G)=sg(G1)^sg(G2)^...^sg(Gn)。

      (2)分别考虑没一个子游戏,计算其SG值。

       SG值的计算方法:(重点)

       1,可选步数为1~m的连续整数,直接取模即可,SG(x) = x % (m+1);

       2,可选步数为任意步,SG(x) = x;

       3,可选步数为一系列不连续的数,用模板计算。

            模板1:打表

    //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;
                }
            }
        }
    }

      模板2: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;
    }

    二,威佐夫博弈

    0,游戏:有两堆各若干的物品,两人轮流从其中一堆取至少一件物品,至多不限,或从两堆中同时取相同件物品,规定最后取完者胜利。

    1,直接结论:

      假设两堆石子为 (x,y)(其中x<y)

      那么先手必败,当且仅当:

      (y-x)*(sqrt(5)+1)/2==x

      其中的 (sqrt(5)+1)/2 ​实际就是1.618,黄金分割数。

     

    三,裴波那契博弈

    0,游戏:有一堆物品,两人轮流取物品,先手最少取一个,至多无上限,但不能把物品取完,之后每次取的物品数不能超过上一次取的物品数的二倍且至少为一件,取走最后一件物品的人获胜。

    1,结论:先手胜当且仅当n不是裴波那契数,n为物品总数。

  • 相关阅读:
    visual studio 2013运行时卡顿 CPU占用超50%的解决方法
    altium designer中Net Label 使用说明
    机器学习中的目标函数、损失函数、代价函数
    我的Android天气app
    序列交换
    挑战多重部分和问题
    kmp算法模式串匹配
    poj3259
    poj3255
    Redis工具类 单机+集群
  • 原文地址:https://www.cnblogs.com/kkkek/p/11619165.html
Copyright © 2020-2023  润新知