gpt4 book ai didi

algorithm - 组合博弈。如果两个玩家都发挥最佳,谁会赢

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:32:39 26 4
gpt4 key购买 nike

Players A and B play a game optimally and move alternately. They start with 1. Each player in his turn multiplies the current number with any integer from [2,9]. If after a player's turn, the number is more than or equal to n, he wins.

A starts. Given n, who wins?

例如,

数字 2,3..,9 是中奖号码(玩家 A 将获胜)

数字 10,11,..,18 正在输(玩家 A 将输)

数字 19,20,..,162 是中奖号码

获胜的策略是什么?如何应用 Sprague-Grundy 定理来解决这个问题?

最佳答案

根据 Sprague-Grundy theorem公平游戏的每个状态都可以分配一个非负整数,称为 Grundy number,这样在这个状态下移动的玩家如果这个数字是 0 就会输,如果这个数字是非零。

如果状态的 Grundy 数已知,则获胜策略是始终移动到 Grundy 数为 0 的状态。

一般游戏的某个状态的Grundy数计算算法如下:

if current player can't make a valid move:
Grundy number := 0 (this player has lost)
else:
for each move in this state:
for each sub-game the game splits into after that move:
compute Grundy number of the sub-game
compute XOR of Grundy numbers of the sub-games
Grundy number := MEX of those XORs

MEX 是最小排斥函数。一组非负整数的 MEX 等于不属于该集合的最小非负整数。

例如:

MEX(0) = 1
MEX(0, 1) = 2
MEX(0, 2) = 1
MEX(0, 1, 2) = 3
MEX(0, 1, 3) = 2
MEX(1, 2, 3) = 0
MEX(10, 100, 1000) = 0

在 Python 3 中针对该游戏的算法的简单实现可能如下所示:

import functools
from itertools import count

def mex(s):
for i in count():
if i not in s:
return i

@functools.lru_cache(10000)
def sprague_grundy(n, cur=1):
if cur >= n:
return 0
move_results = {sprague_grundy(n, cur*move) for move in range(2, 9+1)}
return mex(move_results)

for i in count(1):
print(sprague_grundy(i))

通常,理解 Grundy 数的一般公式的最简单方法是只查看序列并尝试注意其中的关系。在这个游戏中,您可以通过简单地查看玩家 A 在初始状态下获胜的游戏的 n 个数字来找出通用公式,而无需实际计算 Grundy 数字。

但是我们仍然可以看连续n的游戏初始状态的Grundy数的计数(0表示玩家A在初始状态输,1,2,3,4表示玩家 A 获胜):

$ python3 sprague_grundy.py | uniq -c
1 0
1 1
2 2
4 3
1 4
9 0
18 1
36 2
72 3
18 4
162 0
324 1
648 2
1296 3
324 4
2916 0

可能会注意到,对于玩家 A,所有失败的初始状态都是针对

n \in \left( 9\cdot18^k .. 18^{k+1} \right ]: \textup{for} : k=0,1,2,...

或者换句话说,玩家 A 的初始状态是输 iff

\left\lfloor{\log_{18}{\frac{n-1}{9}}}\right\rfloor > \left\lfloor{\log_{18}{\frac{n}{18}}}\right\rfloor

关于algorithm - 组合博弈。如果两个玩家都发挥最佳,谁会赢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28100823/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com