📜  组合博弈论 |第 4 组(Sprague – Grundy 定理)(1)

📅  最后修改于: 2023-12-03 15:11:37.903000             🧑  作者: Mango

组合博弈论 | 第 4 组 (Sprague-Grundy 定理)

  • 作者:OpenAI
  • 时间:2022年5月10日
简介

Sprague-Grundy 定理是组合博弈论中的一个重要定理,可以用于求解一类特殊的博弈问题。在这篇文章中,我们会介绍 Sprague-Grundy 定理的定义、推导过程、以及如何使用它解决博弈问题。

定义

Sprague-Grundy 定理可用于求解任意两人、零和、完全信息、有限回合的游戏的必胜策略。这里有两种等价的定义方式:

  1. 一个状态 $x$ 的 SG 值等于所有 $x$ 的后继状态的 SG 值的 $\text{xor}$ 和加一。
  2. 在一个有向无环图中,一个节点的 SG 值等于所有从该节点出发的边指向的节点的 SG 值的 $\text{xor}$ 和加一。

根据这两个定义,我们可以得到任意状态的 SG 值。

推导过程

我们来看一个具体的例子,有一个博弈问题:一堆石子,两人轮流取走若干个石子,不能不取,最后一颗石子的人获胜。这是一个经典的博弈问题,我们可以用 Sprague-Grundy 定理来解决。

首先,我们把这个问题看成是一个状态为石子数的游戏。对于任意一个石子数 $n$,它的后继状态就是 $n-1,n-2,\ldots,n-k$,其中 $k$ 是最多可以取多少个石子。因为我们每次取走的石子数不能超过 $k$,所以 $k$ 是一个定值。

接下来,我们来考虑状态 $n$ 的 SG 值。根据第一种定义,状态 $n$ 的 SG 值等于所有后继状态的 SG 值的 $\text{xor}$ 和加一。也就是说:

$$ \mathrm{SG}(n) = \mathrm{mex} { \mathrm{SG}(n-1),\ \mathrm{SG}(n-2),\ \ldots,\ \mathrm{SG}(n-k) } $$

其中 $\mathrm{mex}$ 表示取集合中最小的不在集合中出现的自然数。我们可以用 $f(x)$ 表示 $\mathrm{SG}(x)$:

$$ f(x) = \mathrm{mex} { f(x-1),\ f(x-2),\ \ldots,\ f(x-k) } $$

对于 $k=1$ 的情况,这里的 $\mathrm{mex}$ 可以简单的用异或替换,即:

$$ f(x) = \mathrm{mex} { f(x-1) \oplus 1 } $$

整个推导过程的前提是我们要知道 $\mathrm{SG}(0)=0$。这个比较容易理解,因为当石子数为 $0$ 时,游戏必须停止,此时 SG 值为 $0$。

最后我们来看如何利用 SG 值求解博弈问题。如果两个人分别采用最优策略,那么如果某个位置的 SG 值为 $0$,那么该人必胜;反之,如果 SG 值不为 $0$,那么该人必败。因此,我们可以用 DP 求出所有状态的 SG 值,然后通过 SG 值来求解必胜策略。

代码片段
def sg(n: int, k: int) -> int:
    """
    计算石子游戏中 SG 值
    :param n: 石子数
    :param k: 每次可以取的石子数的最大值
    :return: SG 值
    """
    f = [-1] * (n + 1)
    f[0] = 0
    for i in range(1, n + 1):
        s = set()
        for j in range(1, min(i, k) + 1):
            s.add(f[i-j] ^ 1)
        f[i] = mex(s)
    return f[n]

def mex(s: set) -> int:
    """
    求集合 s 中最小的不在其中的自然数
    :param s: 集合
    :return: 最小的不在其中的自然数
    """
    i = 0
    while i in s:
        i += 1
    return i