博弈论与SG函数(Nim游戏)

博弈论与SG函数(Nim游戏)

目录

在本篇,我们考虑的是两个玩家进行游戏,并且不存在随机概率因素(例如随机抽卡)。

我们的目标是找到一个最优策略去赢得游戏而不关心谁是对手。

游戏状态

让我们考虑一个游戏,这有一堆棍子,两个游戏者A和B依次从这一堆棍子中抽走一些,每次只能抽走1,2或3个棍子,最终谁抽走了最后一根棍子谁就是赢家。

这个游戏包含n + 1 n+1 n +1个状态,分别是0 , 1 , 2 , … , n 0,1,2,\ldots,n 0 ,1 ,2 ,…,n,每一个状态i i i代表着场上现在还剩下i i i个棍子,而不管现在的游戏者是谁。

每一个游戏状态分类为两种,一种是 赢态,一种是 输态。博弈论定理告诉我们, 如果一种游戏状态是赢态,那么它经过最优选择之后必然会转移到输态,否则这个游戏状态是输态。

例如n = 15 n=15 n =1 5,状态0 0 0必然是输态,因为已经没有棍子可以抓取,状态1 , 2 , 3 1,2,3 1 ,2 ,3都是赢态,因为都有机会转移到状态0 0 0,而状态4 4 4是输态,因为这个状态没有办法转移到输态上。,依次类推,我们得到一个表格:

状态赢/输0L1W2W3W4L5W6W7W8L9W10W11W12L13W14W15W

做出这个表之后,就很容易的分析这个游戏,我们发现是4 4 4的倍数都是输态, 开局15 15 1 5 是赢态,这说明先手必然会赢

如果n = 16 n=16 n =1 6,那么开局16 16 1 6这个状态是输态,那么先手必然会输。

以上的必然性都是建立在双方都是以最优策略进行博弈,否则不一定存在必然性。

状态图(SG图)

状态图(State Graph)是一个DAG图,揭示了游戏状态如何进行转移,此类游戏必须满足下列条件,才能使用SG图分析:

  • 游戏有两个人参与,二者轮流做出决策,双方均知道游戏的完整信息;(保证状态转移是唯一的)
  • 任意一个游戏者在某一确定状态可以作出的决策集合只与当前的状态有关,而与游戏者无关;(与游戏者无关)
  • 游戏中的同一个状态不可能多次抵达,游戏以玩家无法行动为结束,且游戏一定会在有限步后以非平局结束。(保证是有限DAG图)

满足这些条件的游戏也叫做 公平组合游戏

我们再考虑一个更复杂的游戏:

每次我们拿取的棍子的数量必须是i i i的倍数,并且必须小于i i i,比如说状态8 8 8,游戏者只能拿1 , 2 , 4 1,2,4 1 ,2 ,4个棍子。

当n = 9 n=9 n =9时,我们可以做出状态转移图(SG图):

博弈论与SG函数(Nim游戏)

我们可以确定1 1 1总是输态,因为游戏已经终止,无法操作。

同样,我们可以做出状态表:

状态赢/输1L2W3L4W5L6W7L8W9L

我们发现奇数一定是输态,偶数一定是赢态。

; Nim 游戏

有 n n n 堆物品,每堆有 a i a_i a i ​ 个,两个玩家轮流取走任意一堆的任意个物品,但不能不取,取走最后一个物品的人获胜。

Nim 游戏的状态是一个n n n元组,定义为[ x 1 , x 2 , … , x n ] [x_1,x_2,\ldots,x_n][x 1 ​,x 2 ​,…,x n ​],其中x i x_i x i ​为第i i i堆的物品的数量。

更一般的,我们总结如下定理:

  • 定理 1:没有后继状态的状态是必败状态。
  • 定理 2:一个状态是必胜状态当且仅当存在至少一个必败状态为它的后继状态。
  • 定理 3:一个状态是必败状态当且仅当它的所有后继状态均为必胜状态。

对于定理 1,如果游戏进行不下去了,那么这个玩家就输掉了游戏。

对于定理 2,如果该状态至少有一个后继状态为必败状态,那么玩家可以通过操作到该必败状态;此时对手的状态为必败状态——对手必定是失败的,而相反地,自己就获得了胜利。

对于定理 3,如果不存在一个后继状态为必败状态,那么无论如何,玩家只能操作到必胜状态;此时对手的状态为必胜状态——对手必定是胜利的,自己就输掉了游戏。

有了以上三条定理和SG图,我们可以在O ( ∏ a i ) O(\prod a_i)O (∏a i ​)的时间内计算出所有的状态的输赢。

但是这样的时间复杂度太高,我们有更好的办法去解决这个问题。

Nim 和

定义一个状态的Nim和为S = x 1 ⊕ x 2 ⊕ … ⊕ x n S=x_1 \oplus x_2 \oplus \ldots \oplus x_n S =x 1 ​⊕x 2 ​⊕…⊕x n ​。

一个状态为输态,当且仅当S = 0 S=0 S =0,否则为赢态。

为什么状态与异或和有关?

我们需要证明以下三个定理:

  • 定理 1:没有后继状态的状态是必败状态。
  • 定理 2:对于S ≠ 0 S \neq 0 S ​=0 的局面,一定存在某种移动使得S = 0 S = 0 S =0。
  • 定理 3:对于S = 0 S = 0 S =0 的局面,一定不存在某种移动使得S = 0 S = 0 S =0。

对于定理1,即结束[ 0 , 0 , … , 0 ] [0,0,\ldots,0][0 ,0 ,…,0 ]的异或和一定为0 0 0。

对于定理2,我们会修改x i x_i x i ​,使得变为x i ′ x_i’x i ′​,且x i ′ < x i x_i’ < x_i x i ′​<x i ​,x i ′ = k ⊕ x i x_i’ = k \oplus x_i x i ′​=k ⊕x i ​。记S S S在二进制下的最高有效位为b b b,我们总是能找到一个x i x_i x i ​在二进制下的b b b位为1 1 1,那么我们就可以将这一位变为0 0 0,进而可以调整后面的位,使得S = 0 S=0 S =0,并且调整过后的x i ′ < x i x_i’ < x_i x i ′​<x i ​。

对于定理3,修改x i x_i x i ​的任意一位都会使S S S变化,因此一定不存在某种移动使得 S = 0 S = 0 S =0。

SG函数

Sprague-Grundy 定理总结了一般的组合博弈游戏的解决方案。

  • 这有两个玩家互相进行游戏。(回合制)
  • 游戏的局面由状态组成,每一个状态的移动都是确定的,不依赖于当前状态是谁的回合。(玩家无关性)
  • 当玩家无法进行操作的时候游戏便结束。因此,这个游戏迟早会结束。(有穷性)
  • 在游戏开始之前,游戏玩家就已经知道所有状态的转移路径,并且无法改变,也不存在概率随机因素。(确定性)

SG函数的思想就像定义Nim和一样,我们为每一个状态定义一个Grundy数字。

Grundy数字

定义一个状态的Grundy数字(Grundy-Number)为:

G N k = mex ( { g 1 , g 2 , … , g n } ) GN_k = \text{mex}({g_1,g_2,\ldots,g_n})G N k ​=mex ({g 1 ​,g 2 ​,…,g n ​})

这里的g 1 , g 2 , … , g n g_1,g_2,\ldots,g_n g 1 ​,g 2 ​,…,g n ​是我们量化一个状态的数字,g 1 , g 2 , … , g n g_1,g_2,\ldots,g_n g 1 ​,g 2 ​,…,g n ​分别是状态k k k的后继状态的G N GN G N。

而mex \text{mex}mex函数的意思是,返回没有出现在g 1 , g 2 , … , g n g_1,g_2,\ldots,g_n g 1 ​,g 2 ​,…,g n ​最小的非负整数,例如:mex ( { 0 , 1 , 3 } ) = 2 \text{mex}({0,1,3})=2 mex ({0 ,1 ,3 })=2。

我们定义S G SG S G函数为:

S G ( k ) = G N k = mex y i ∈ Y ( { S G ( y i ) } ) SG(k) = GN_k = \text{mex}_{y_i \in Y}({SG(y_i)})S G (k )=G N k ​=mex y i ​∈Y ​({S G (y i ​)})

其中Y Y Y集合是状态k k k的后继状态的集合。

特别的,终止状态没有后继,我们记S G ( ϕ ) = 0 SG(\phi) = 0 S G (ϕ)=0。

这样,每一个有向图都可以转换成一个SG图,节点上的点权为该状态的SG函数的值。

例如:

博弈论与SG函数(Nim游戏)

并且有 第一SG定理

一个状态是输态当且仅当G N = 0 GN = 0 G N =0 ,否则为赢态(SG函数值为正整数)。

当一个状态的G N = 0 GN=0 G N =0那么其后继节点一定都是正整数,如果一个状态是x x x为正整数,那么,他的前驱一定包括0 , 1 , … , x − 1 0,1,\ldots,x-1 0 ,1 ,…,x −1,特别的一定包括0 0 0。

正好满足我们SG图的定义。

; 组合博弈游戏

考虑如下一个游戏,两个玩家面前有一个棋盘,有些地方是可以走的,有些地方是不能走的,每个回合,一个玩家移动人物,可以连续移动人物向上走,或者连续移动人物向右走,不能不移动。当移动不了人物的时候游戏结束,并且最后一个移动人物的玩家获胜。

博弈论与SG函数(Nim游戏)

其中”@”代表的当前人物的位置,”*”代表的是可以移动的范围,图二写出了每一个点的G N GN G N值。

这是一个单个Nim 游戏,类似的我们可以构造出组合Nim游戏。玩家现在有n n n个棋盘,每个回合玩家可以任选一个棋盘进行操作。

博弈论与SG函数(Nim游戏)

按照Nim 和的思想,我们可以定义这个游戏的Nim 和为:

S = a 1 ⊕ a 2 ⊕ … ⊕ a n S = a_1 \oplus a_2 \oplus \ldots \oplus a_n S =a 1 ​⊕a 2 ​⊕…⊕a n ​

其中a i a_i a i ​是第i i i个棋盘的S G SG S G函数值或G N GN G N值。

同理,当且仅当该状态的S = 0 S=0 S =0,这个状态是输态,否则是赢态。

如此,我们有 第二SG定理

一个组合Nim 游戏的初始S S S 值如果为0 0 0 ,那么先手一定必输。否则先手必赢。

同样的,此定理在双方都是最优策略的情况下必然性成立。

Grundy 游戏

Grundy 游戏与组合博弈游戏不同的是,Grundy 游戏中存在单一Nim游戏,也存在组合Nim游戏。

例如,我们还是考虑木棍游戏。两个游戏玩家每个回合任选一堆棍子,然后把它们分成数量不相等的两堆棍子,最后无法分解游戏结束,最后一个分解的玩家胜利。

我们定义游戏状态为f ( n ) f(n)f (n ),其中n n n为棍子的数量,且只有一堆棍子。例如n = 8 n=8 n =8,那么计算f ( 8 ) f(8)f (8 ),8 8 8可以有如下拆分为1 + 7 1+7 1 +7,2 + 6 2+6 2 +6或3 + 5 3+5 3 +5,那么:

f ( 8 ) = mex ( { f ( 1 ) ⊕ f ( 7 ) , f ( 2 ) ⊕ f ( 6 ) , f ( 3 ) ⊕ f ( 5 ) } ) f(8) = \text{mex}({f(1) \oplus f(7),f(2) \oplus f(6),f(3) \oplus f(5)})f (8 )=mex ({f (1 )⊕f (7 ),f (2 )⊕f (6 ),f (3 )⊕f (5 )})

这个步骤可以通过动态规划来计算出全部的f ( n ) f(n)f (n )的值。计算出f ( 8 ) = 2 f(8) = 2 f (8 )=2,因此当n = 8 n=8 n =8的时候,先手必胜。

例题

LeetCode 292

P2197

#include

using namespace std;

#define FR freopen("in.txt", "r", stdin)
#define FW freopen("out.txt", "w", stdout)

typedef long long ll;

void solve()
{
    int n;
    scanf("%d", &n);
    int XOR = 0;
    for (int i = 1; i  n; i++)
    {
        int val;
        scanf("%d", &val);
        XOR ^= val;
    }

    if (XOR == 0)
    {
        printf("No\n");
    }
    else
    {
        printf("Yes\n");
    }
}

int main()
{
    int T;
    scanf("%d", &T);
    while (T--)
    {
        solve();
    }
    return 0;
}

Original: https://blog.csdn.net/jiahonghao2002/article/details/119480284
Author: 爱寂寞的时光
Title: 博弈论与SG函数(Nim游戏)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/783593/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • python中 s如何输入_Python:如何在Pandas中使用或获取列标题并将其用作输入/值

    我有以下脚本,该脚本使用Pandas生成空数据帧:import pandas as pd import datetime Creating a list of row header…

    Python 2023年8月22日
    042
  • 基于Kubernetes容器云平台的CI/CD

    基于 Kubernetes 实现 CI/CD 配置,其实和往常那些 CI/CD 配置并没有太大区别。都是通过 提交代码,拉取代码,构建代码,发布代码来实现的。 只不过要是通过 K8…

    Python 2023年10月9日
    043
  • 3.3 设置坐标轴的长度和范围

    3.3 设置坐标轴的长度和范围 前阵子在跟着课程学习springboot项目,所以以及有好几天没有学习python了,哈哈哈哈~现在的话尽可能每天都合理安排一下学习规划才行。今天将…

    Python 2023年9月7日
    044
  • JDK源码分析实战系列-PriorityQueue

    完全二叉树 一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵…

    Python 2023年10月14日
    044
  • Pandas 多层级索引 Python 数据处理案例指南

    今天我们来聊一下 Pandas当中的数据集中带有多重索引的数据分析实战 通常我们接触比较多的是单层索引,而多级索引也就意味着数据集当中的行索引有多个层级,具体的如下图所示 ; 导入…

    Python 2023年8月7日
    046
  • 【Python】父类调用子类中的方法和属性

    众所周知,python中子类继承了父类,子类可以调用父类中的方法和属性,那么父类如何调用子类中方法和属性呢? `class Father(object): def father_a…

    Python 2023年8月9日
    054
  • pytorch梯度的计算过程

    1、基础知识: 与numpy中的基本操作相似, pytorch 的作用是引入GPU加快运算, 增加图形界面, 适合大数据运算, 尤其是deep learning gradient …

    Python 2023年8月24日
    062
  • 机器学习(1)——Python数据处理与绘图

    1 numpy数组使用 1.1 numpy生成数组 1.2 numpy数组属性 1.3 数组的索引和切片 1.4 numpy数组运算 1.5 随机数 1.6 数组副本和视图 1.7…

    Python 2023年8月23日
    043
  • matplotlib中自定义scale——针对普通标度与colorbar

    文章目录 背景 方案一(题外话) 方案二 自定义scale * 理论部分 核心代码 数据标注 多组数据使用heatmap:自定义color bar的scale 背景 现在我对比了1…

    Python 2023年9月3日
    035
  • ES系列二之常见问题解决

    上篇ES系列一之java端API操作结束后本以为就相安无事了,但生产的问题是层出不穷的;下面我就再记录下近几周遇到的问题以及解决方案; 一 更新ES信息报错 报错信息如下: Use…

    Python 2023年10月14日
    041
  • [ 红队知识库 ] 常见防火墙(WAF)拦截页面

    🍬 博主介绍 👨‍🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】🎉点赞➕评论➕…

    Python 2023年9月15日
    050
  • python实现简易数独小游戏

    起源 既然”数独”有一个字是”数”,人们也往往会联想到数学,那就不妨从大家都知道的数学家欧拉说起,但凡想了解数独历史的玩家在网络、书…

    Python 2023年9月17日
    049
  • 进程

    理论知识 操作系统背景知识 顾名思义,进程即正在执行的一个过程。进程是对正在运行程序的一个抽象。 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重…

    Python 2023年6月6日
    098
  • 课程笔记6:Scrapy框架——Extension的使用

    Extension(扩展)简介 Scrapy提供了一些Extension机制,可以让我们添加和扩展一些自定义的功能(监听Scrapy运行过程中的信号,在发生某个事件时,执行我们自定…

    Python 2023年10月2日
    029
  • Django规范化编程1

    Django技能复苏 依旧是吃吹不忘挖井人环节:https://blog.csdn.net/weixin_41790086/article/details/80726480 MVC…

    Python 2023年8月4日
    037
  • ICRA2022 SLAM进展—激光SLAM

    激光SLAM文章列表 ICRA2022 SLAM Paper List Learning Spatiotemporal Occupancy Grid Maps for Lifelo…

    Python 2023年10月10日
    044
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球