此文为以下博客做的摘要:

https://blog.csdn.net/strangedbly/article/details/51137432

----------------------------------------------------------------------------------------

1、定义P-position和N-positon

P表示Previous,N表示Next。

即上一个移动的人有必胜策略的局面是P-position,“先手必败”或“后手必胜”,现在移动的人有必胜策略的局面是N-positon,“后手必败”或“先手必胜”。下面为更严谨的定义:

1、无法进行任何移动的局面(即terminal position)是P-position;

2、可以移动到P-position的局面是N-position;

3、所有移动都导致N-position的局面是P-position。

根据定义,不重现局面,那么positions的集合可以进行拓扑排序,并且能通过定义判断为P-position还是N-position。

2、Nim游戏

对于一个Nim游戏的局面(a1, a2, ...an),它是P-position当且仅当 a1^a2^...^an = 0,其中 ^ 表示异或运算。

要证明这个定理,基本上是证明这种运算符合上述position的定义。即证明三个命题:1、这个判断将所有无法移动的局面判为P-position;2、被判为N-position的局面一定可以移动到某个P-position;3、被判为P-position的局面无法移动到某个P-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'不是一个合法的移动。证毕。

3、Sprague-Grundy函数

首先给出这个函数适用范围,貌似所有博弈的题目都是符合这个范围。现在来研究似乎更为一般的游戏:给定一个有向无环图和一个其实顶点上的一枚棋子,两名选手交替将这棋子沿有向边移动,无法移动者判负。事实上,这个游戏可以认为是所有Impartial Combinatorial Games的抽象模型。即任何一个ICG都可以通过把每个局面看成一个顶点,对每个局面和它的子局面连一条有向边来抽象成这个“有向图游戏”。

首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数。例如mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。

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

来看一下SG函数的性质。首先,所有的terminal position所对应的顶点,也就是没有出边的顶点,其SG值为0,因为它的后继集合是空集。下面为原作图

(pic1)

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

对于一个g(x) != 0的顶点,必定存在一个后继 y 满足 g(y) = 0。

即顶点 x 代表的position为P-position,当且仅当 g(x) = 0。相应地N-position为 g(x) != 0。所以有向无环图的每个顶点SG值能够计算出来,就能找到每种局面的必胜策略。但SG函数的用途远没有这么简单。如果将有向图游戏变复杂,比如,有向图上不止有一枚棋子,而是有n枚,每次可以人选一颗移动,这时怎么找必胜策略?

考虑一下顶点的SG值的意义。当g(x) = k时,表明对于任意一个 0 <= i < k,都存在x的一个后继 y 满足g(y) = i。即当某棋子的SG值为k时,我们可以把它变成0、变成1、……、变成k-1,但绝对不能保持k不变。这类似于Nim游戏,Nim游戏的规则就是:每次选择一堆数量为k的石子,可以把它变成0、变成1、……、变成k-1,但绝对不能保持k不变。这表明,如果将n枚棋子所在的顶点的SG值看作n堆相应数量的石子,那么这个Nim游戏的每个必胜策略都对应于原来这n枚棋子的必胜策略!

对于n个棋子,设它们对应的顶点的SG值分别为(a1,a2,...,an),再设局面(a1,a2,...,an)时的Nim游戏的一种必胜策略是把ai变成k,那么原游戏的一种必胜策略就是把第i枚棋子移动到一个SG值为k的顶点。其实我们还是只要证明这种多棋子的有向图游戏的局面是P-position当且仅当所有棋子所在的位置的SG函数的异或为0。这个证明与上面的Bouton's Theorem几乎是完全相同的,只需要适当的改几个名词就行了。

刚才,为了使问题看上去更容易一些,认为n枚棋子是在一个有向图上移动。但如果不是在一个有向图上,而是每个棋子在其对应的有向图上,每次可以任选一个棋子(也就是任选一个有向图)进行移动,这样也不会给结论带来任何变化。

所以我们可以定义有向图游戏的和(Sum of Graph Games):设G1、G2、……、Gn是n个有向图游戏,定义游戏G是G1、G2、……、Gn的和(Sum),游戏G的移动规则是:任选一个子游戏Gi并移动上面的棋子。Sprague-Grundy Theorem就是:g(G)=g(G1)^g(G2)^...^g(Gn)。也就是说,游戏的和的SG函数值是它的所有子游戏的SG函数值的异或。

任何一个ICG都可以抽象成一个有向图游戏。所以“SG函数”和“游戏的和”的概念就不是局限于有向图游戏。我们给每个ICG的每个position定义SG值,也可以定义n个ICG的和。所以说当我们面对由n个游戏组合成的一个游戏时,只需对于每个游戏找出求它的每个局面的SG值的方法,就可以把这些SG值全部看成Nim的石子堆,然后依照找Nim的必胜策略的方法来找这个游戏的必胜策略了!(Nim其实就是n个从一堆中拿石子的游戏求SG的变型,总SG=n个sg的异或)。(very important)

有n堆石子,每次可以从第1堆石子里取1颗、2颗或3颗,可以从第2堆石子里取奇数颗,可以从第3堆及以后石子里取任意颗……我们可以把它看作3个子游戏,第1个子游戏只有一堆石子,每次可以取1、2、3颗,很容易(看下图pic2)看出x%4==0时处于P局面,即x颗石子的局面的SG值是x%4,(即把pic2中的值改成原值%4)。第2个子游戏也是只有一堆石子,每次可以取奇数颗,经过简单的画图可以知道这个游戏有x颗石子时的SG值是x%2。第3个游戏有n-2堆石子,就是一个Nim游戏。对于原游戏的每个局面,把三个子游戏的SG值异或一下就得到了整个游戏的SG值,然后就可以根据这个SG值判断是否有必胜策略以及做出决策了。其实看作3个子游戏还是保守了些,干脆看作n个子游戏,其中第1、2个子游戏如上所述,第3个及以后的子游戏都是“1堆石子,每次取几颗都可以”,称为“任取石子游戏”,这个超简单的游戏有x颗石子的SG值显然就是x。其实,n堆石子的Nim游戏本身不就是n个“任取石子游戏”的和吗?

(pic2)

所以,对于我们来说,SG函数与“游戏的和”的概念不是让我们去组合、制造稀奇古怪的游戏,而是把遇到的看上去有些复杂的游戏试图分成若干个子游戏,对于每个比原游戏简化很多的子游戏找出它的SG函数,然后全部异或起来就得到了原游戏的SG函数,就可以解决原游戏了。

以下是本文最重要的部分:

解题模型:

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:打表

 1 //f[], 可以取走的石头个数
 2 //sg[],SG函数值
 3 //mex[],mex{}
 4 int f[MAXN], sg[MAXN], mex[MAXN];
 5 void getSG(int n)
 6 {
 7     int i, j;
 8     memset(sg, 0, sizeof(sg));
 9     for(i = 1;i <= n;++i)
10     {
11         memset(mex, 0, sizeof(mex));
12         for(j = 1;f[j] <= i;++j)
13             mex[sg[i - f[j]] = 1;
14         for(j = 0;j <= n;++j)
15             if(mex[j] == 0)
16             {
17                 sg[i] = j;
18                 break;
19             }
20     }
21 }

  模板2:DFS

//s[i] 数组要从小排到大,SG函数要初始化为 -1, 每个集合只需初始化一遍
//n是集合s 的大小,s[i]是定义的特殊取法规则的数组
int s[105], sg[10005], n;
//memset(sg, -1, sizeof(sg));
//sort(s, s + n);
int SG_dfs(int x)
{int i;if(sg[x] != -1)return sg[x];bool vis[105];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;//mex{}
        }}int e;for(i = 0;;++i)if(!vis[i]){e = i;break;}return sg[x] = e;
}

  首选打表,实在不行才用DFS。

3.计算sg(G)=sg(G1)^sg(G2)^...^sg(Gn),sg(G)=0,即P-Position,即先手必败。

--------------------------------------------------------------------------------------------

原博主下面还有题,另外也开了一篇写题的博客

转载于:https://www.cnblogs.com/shuizhidao/p/9271712.html

(转)博弈 SG函数相关推荐

  1. 点分治问题 ----------- P3727 曼哈顿计划E[点分治+博弈SG函数打表找规律]

    题目链接 解题思路: 1.首先对于每个操作我们实际上是一个博弈问题 对于k=1的操作就是很基础的NIM游戏就是找到一条链的异或和为0 对于k=2的操作通过达打表找规律: 如果s是奇数那么偶数的SG函数 ...

  2. NIM博弈+SG函数求解

    ICG 给定一个有向无环图和一个起始顶点上的一枚棋子,两名选手交替的将这枚棋子沿有向边进行移动,无法移动者判负. 这个游戏可以认为是所有 Impartial Combinatorial Games 的 ...

  3. CodeForces - 850C Arpa and a game with Mojtaba(博弈+sg函数)

    题目链接:点击查看 题目大意:给出n个数,两个人轮流按照规则操作,不能操作的人即为失败,规则很简单,每次找一个质数p的k次幂,记做x=,将数组中所有包含x倍数的数都除以x,必须保证至少有一个数可以除以 ...

  4. 博弈-sg函数的原理和优化(hdu-1536)

    sg函数:sg函数是博弈中的确定一个position性质的一个函数,全称是sprague-grundy. 性质1:对于所有的p-position,都有sg = 0:对于所有的n-position都有s ...

  5. 【博弈论】博弈论入门笔记(四类基础博弈+SG函数)

    『博弈论定义』 博弈论又被称为对策论(Game Theory):是二人或多人在平等的对局中各自利用对方的策略变换自己的对抗策略,达到取胜目标的理论.博弈论是研究互动决策的理论.博弈可以分析自己与对手的 ...

  6. HDU 1846-Brave Game(巴什博弈-SG函数)

    Brave Game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  7. 【博弈 —— SG函数详解+例题解析】

    前言 如果你对这篇文章可感兴趣,可以点击「[访客必读 - 指引页]一文囊括主页内所有高质量博客」,查看完整博客分类与对应链接. SG函数解析: 博弈游戏的本质是一个有向图游戏,每个状态(局面)是一个图 ...

  8. 数学基础(四)博弈论(巴什博弈~威佐夫博弈(黄金分割率)~尼姆博奕~斐波那契博弈~SG函数模板)

    一.巴什博弈 1.问题模型 只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个,最后取光者得胜. 2.解决思路: 当n=m+1时,由于一次最多只能取m个,所以无论先取者拿走多 ...

  9. hdu2897邂逅明下——博弈sg函数的应用

    邂逅明下 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

最新文章

  1. mysql Table 'plugin' already exists
  2. Asp.net MVC, 谁吃了我的id参数值?
  3. php上传视频文件代码,php上传视频的代码
  4. 微服务API设计的实践与思考总结
  5. 两雄争霸:解读MSU2019年度视频编码大赛
  6. 路径问题--转发、重定向、表单、超链接
  7. linux 修改普通用户的 max user process
  8. 深度优先遍历(DFS)- Letter CasePermutation - Combinations
  9. [转载] [python标准库]math——数学函数
  10. QuickHit游戏
  11. JavaScript自定义滚动条
  12. 三方演化博弈复制动态方程matlab仿真(输入参数较多时)——matlab2016a版本
  13. CMS漏洞(发货100CMS、SHECMS、ZHCMS、MACCMS)详解实战
  14. 人工智能技术岗位面试要注意什么?
  15. 把我给另外一个朋友的炒股劝告发给你一遍,希望你可以得到帮助!
  16. 通达云OA被阿里云列为企业办公首推应用
  17. 串口重定向(STM32 F411RET6开发版)
  18. 红警ol服务器维护中1003,不止于经典,全球唯一正版授权《红警OL》登录UP2018腾讯新文创生态大会...
  19. [‘XXX‘] not found in axis
  20. 目前最经典有效的“阅读方法”——SQ3R阅读法

热门文章

  1. 阿里数据:2020七大数据技术领域趋势展望
  2. C语言知识体系思维导图
  3. 零基础学Java编程一定要上Java培训机构吗
  4. MySQL复习资料(七)——MySQL-存储过程
  5. 支付宝招兼职“找茬程序员” 不用坐班/最高奖励36万
  6. 《西游记》原著的一点读后感
  7. MySQL小误区:关于set global sql_slave_skip_counter=N 命令的一些点
  8. mysql中int、bigint、smallint 和 tinyint的区别与长度的含义
  9. Python虚拟环境virtualenv的安装与使用详解(转)
  10. 关于推荐系统中的长尾商品