首页 > 其他分享 >浅谈SG函数

浅谈SG函数

时间:2023-07-22 19:44:36浏览次数:47  
标签:状态 浅谈 必败 游戏 必胜 oplus SG 函数

公平组合游戏和策梅洛定理

公平组合游戏是指满足以下条件的一个博弈游戏:

  1. 游戏对参加的两人公平,没有随机因素,信息公开透明
  2. 两名玩家轮流行动,一名玩家不能行动时游戏结束。
  3. 游戏状态有限,且游戏一定能在有限步内结束,没有平局
  4. 游戏局势不能区分玩家

对于一个公平组合游戏,我们会关心给定初始状态,它是否存在先手必胜的策略。

为了解决这个问题,就有了策梅洛定理。策梅洛定理指出,公平组合游戏中的任何一个状态,要么先手有必胜策略,要么后手有必胜策略。

证明这件事,我们可以将一个状态看作一个点,每个状态向它的后继状态连边,形成一个有向图。因为公平组合游戏的定义中有一定在有限步内结束,所以这个有向图中不能有环,所以这又是个拓扑图。我们将操作者必败的点称为必败态,操作者必胜的点称为必胜态。
对于拓扑图的没有出度的点,必为必败态。如果一个点的后继都是必胜态,则当前点为必败态。如果一个点的后继存在必败态,则当前点为必胜态。可以发现除去这两种条件,没有其它条件了,所以每个点的状态都是确定的。于是我们得到了上述结论。

得到这个结论,我们对于所有的公平博弈游戏就有了一种通解了:对抗搜索,也就是使用记忆化搜索来完成博弈的过程。

SG函数

虽然我们有了通解,可以使用记忆化搜索完成,但我们寻求更优的做法。

先举一个例子:有一堆 \(n\) 个石头,每次能拿走 \(1\sim 3\) 个石头,取走最后一个石头的人获胜。

这是一个很经典也很简单的公平组合问题。但是如果不止一堆呢?搜索的总状态数会大大增加。但我们发现每一堆是等价的,所以我们可以算出每一堆的获胜情况,进而推出最后的获胜情况。如果用 \(0\) 表示必败态,\(1\) 表示必胜态,那么最后的结果为所有堆结果的异或和。
等等,我们需要考虑一件事,必胜态真的必胜吗?这可能未必,就比如 \(5\) 既可以转移到 \(4\) 这个必败态,也可以转移到 \(2\) 这个必胜态,也就是 \(5\) 这个状态的最终胜负情况是可以通过先手的操作改变的,自然也不能和原来的必胜态一概而论。

这时候我们引出一个阶数的概念,令必败态为 \(0\) 阶,能转移到必败态的必胜态为 \(1\) 阶状态,能转移到必败态和 \(1\) 阶状态的必胜态为 \(2\) 阶状态。于是我们得到一个 \(n\) 阶状态的定义:能转移到 \(0\sim n-1\) 阶状态中任意一阶的状态。
我们用 \(SG(S)\) 表示状态 \(S\) 的阶。根据阶数的定义,我们可以知道,当且仅当 \(SG(S)=0\) 时,状态 \(S\) 为必败态。且 \(SG(S)=\mathop{\mathrm{mex}}\{SG(S')\mid S\rightarrow S'\}\),其中 \(S\rightarrow S'\) 表示能从状态 \(S\) 转移到 状态 \(S'\)。这个 \(mex\) 很好理解,因为 \(SG(S)\) 以下的阶数都能达到,所以状态 \(S\) 的阶数为 \(SG(S)\)。

SG 定理

先给出结论,\(SG(A+B)=SG(A)\oplus SG(B)\)

令 \(A'\) 为 \(A\) 的后继状态,\(B'\) 为 \(B\) 的后继状态。\(SG(A)=a,SG(B)=b,SG(A')=a',SG(B')=b'\),根据计算式可以得到 \(a'\in [0,a-1]\cup [a+1,+\infty],b'\in [0,b-1]\cup [b+1,+\infty]\)。首先可以得到 \(a' \in [a+1,+\infty]\) 和 \(b'\in [b+1,+\infty]\) 是无意义的,因为对方可以转移回 \(a\) 阶状态和 \(b\) 阶状态。剩下的考虑分类讨论。

1. a=b=0

此时显然,因为每局游戏先手都必败,所以他将一直是先手,所以他最终必败。

2. 其它

考虑使用数学归纳法证明。我们假定局面 \(A+B'\) 和 \(B+A'\) 均满足要求,所以存在 \(SG(A+B')\in[0,a\oplus b'),SG(A'+B)\in[0,a'\oplus b)\)。令 \(c=a\oplus b\),\(t\) 在二进制下有 \(sum\) 个 \(1\),\(p_i\) 表示 \(c\) 的第 \(i\) 个为 \(1\) 的位置。则 \(c=\sum\limits_{i=1}^{sum}2^{p_i}\)。我们找到 \(p_1\) 该位如果要为 \(1\),一定为一个该位为 \(1\) 的数和一个该位为 \(0\) 的数异或得到,\(a\oplus b'\) 和 \(b\oplus a'\) 的并集一定包含长为 \(2^{p_1}\) 的区间 \([0,2^{p_1})\),令第 \(p_1\) 位均为 \(1\),可以同理得到一定包含 \([2^{p_1},2^{p_1}+2^{p_2})\),一步步往下走可以得到所有取值集合的并集为 \([0,c)\),根据计算式,得到 \(SG(A+B)=c=SG(A)\oplus SG(B)\),也就证明了 SG 定理的正确性。

参考资料

标签:状态,浅谈,必败,游戏,必胜,oplus,SG,函数
From: https://www.cnblogs.com/luoshen0/p/17553404.html

相关文章

  • python std函数调用
    Python标准库函数调用Python是一种功能强大且易于学习的编程语言,它提供了丰富的标准库来支持各种不同的编程任务。这些标准库函数被广泛应用于开发Web应用、数据分析、人工智能等领域。本文将介绍一些常用的Python标准库函数调用,并提供相应的代码示例。1.时间日期处理Python的d......
  • PostGIS:ST_LineLocatePoint函数
    ST_LineLocatePoint是PostGIS中的一个函数,用于计算点在线段上的位置。函数的语法如下:ST_LineLocatePoint(geometrylinestring,geometrypoint);参数说明:geometrylinestring:表示线段的几何图形对象,通常是一个LineString类型的几何图形。geometrypoint:表示要计......
  • python函数入参配置的技巧
    如下的代码大家应该都见过:deffunc1(n):ifn<=0:print('请输入一个整数!')func1(int(input()))elifn<=2:return1else:returnfunc1(n-1)+func1(n-2)这个是是一个简单的函数处理,得到斐波那契数列的第N个数的值,这里的入参就......
  • python数据分析常用函数
    Python数据分析常用函数实现流程作为一名经验丰富的开发者,我将帮助你实现Python数据分析常用函数。下面是整个流程的步骤表格:步骤描述步骤1导入所需的库步骤2载入数据步骤3数据清洗步骤4数据探索步骤5数据可视化步骤6数据分析接下来,让我逐步为......
  • python如何给有主函数的程序传递参数
    Python如何给有主函数的程序传递参数在Python中,我们可以通过命令行参数或者配置文件来给有主函数的程序传递参数。下面将介绍两种常用的方法,并提供相应的代码示例。方法一:命令行参数命令行参数是在运行Python程序时通过命令行传递的参数。在Python中,我们可以使用sys模块的argv属......
  • [TSG@Site开发日志3]从C#到Qt,再从Qt到C# 和 Qt的组合开发,浅谈在采集端工控设备开发中
    [TSG开发日志3]从C#到Qt,再从Qt到C#,浅谈不同技术之间选型的利与弊当前在South公司的开发历经了几个时代,第一个时代是用C#进行的开发,第二个时代是从C#向Qt逐渐转型,第三个时代是我现在站在十字路口上,又需要将采集端软件从Qt的路上拉回来。为什么先看看AI怎么说选择使用C#还是Qt来......
  • Excel 中的技巧函数
    Excel常用函数公式20例,第7条条件查询,其中第一列为要查询的列,如果不是怎么办?可以参考Excel函数之王,Vlookup到底怎么用?IF({1,0},B:B,A:A)......
  • 对于散列函数的定义与整数散列
    散列定义对于一个简单的问题,给定N个正整数和M个正整数,要求当M个正整数中的元素如果在N中出现的话就输出YES。一个很直观的思想即对于遍历M个正整数,然后在N中进行查找,找到的话就输出YES,但是这样的话,其时间效率将达到O(N*M),当N和M非常大的时候,这个方法根本不能满足实现。然而我们......
  • SQL日期操作函数(CONCAT、DATE_FORMAT、LAST_DAY)
    获取某月底日期:SELECTLAST_DAY('2021-07-01')ASmonth_end_date;拼接年月格式:CONCAT(DATE_FORMAT(hp.planned_payment_date,'%Y-%m'),'-01')如果数据库内存的是2023-07-19经过处理后会变成:2023-07-01SELECTbp.UNIT_ID......
  • c语言计算整数各位数字之和函数
    1、用C语言写一段,可以计算任意两个输入数的和的程序2、求1到100之和用C语言怎么编程3、c语言编写一个求三个整数和的程序并输出结果。4、用c语言编程如何实现求和的程序代码?用C语言写一段,可以计算任意两个输入数的和的程序1、那么因为阿拉伯数字只有10个所以10进制大......