zoukankan      html  css  js  c++  java
  • 我对SG函数的理解

    转载请注明原作者:http://blog.csdn.net/maxwei_wzj/
    对于某一类游戏(博弈),我们可以把游戏中的各个状态看作点,状态之间的转移看作有向边,构成一个有向无环图,把博弈的过程看成是两个人拿一个棋子轮流在图上面走,如果轮到某一方时走不动就算输。这可以看做ICG(公平组合游戏,Impartial Combinatorial Games)的一种抽象模型,例如著名的Nim游戏就是一个ICG。这类游戏的每一个状态都有先手必胜或先手必败的性质,我们把先手必败的状态称为P-position,先手必胜的状态称为N-position。事实上P/N-position还可以这样定义:1.无法继续走的点是P-position;2.有出边指向P-position的点是N-position;3.任何出边都指向N-position的点是P-position。按照这个定义,我们就可以对于任意一个ICG,算出任意一个状态的P/N-position性质了。
    这个时候我们在这样一个模型上的每一个点定义SG(Sprague-Garundy)函数:一个有向无环图上的一个点i的SG函数g(i)定义如下:如果该点没有出边,g(i)=0,否则定义一个mex(minimal excludant)操作,这是对一个集合进行的操作,返回值为集合中所不包含的最小的非负整数,那么g(i)=mex{g(x)|ix}。显然对于一个有向无环图,我们都能在O(×)时间内求出所有点的SG函数值,那么这个SG函数又有什么性质呢?设g(i)=k,这就表示从点i可以走到一个SG函数值等于0,1,2,...,k1的点,这是不是很像Nim游戏中的“取石子”操作?Nim游戏中,可以将一个有k个石子的堆变为有0,1,2,...,k1个石子的堆,而对于任何一个ICG,从一个g(i)=k的状态可以走到一个g(i)=0,1,2,...,k1的状态,这就说明ICG和Nim游戏有着一种联系。
    而上面的有向图游戏除了终止点外,都是先手必胜的(因为可以直接走到g(i)=0的点),我们需要研究更加复杂的游戏,那么我们定义一个“组合游戏”:一个游戏由若干个“子游戏”组成,每个子游戏都是一个ICG,而整个游戏要求每次挑选一个子游戏进行行动,那么这样一个游戏的P/N-position性质要怎么计算呢?前面我们介绍了Nim游戏与ICG之间的联系,而在研究Nim游戏时我们有一个结论:如果每堆石子的数量异或起来值为0,那么先手必败,否则先手必胜。那么我们类比Nim游戏和上面的组合游戏,发现Nim游戏中每堆石子的数量和组合游戏中每一个子游戏的初始状态的SG函数值是对应的,那么Nim游戏中的结论也可以套到这样的组合游戏中来:若组合游戏的每一个子游戏中初始状态的SG函数值异或起来等于0,那么这个组合游戏先手必败,否则先手必胜。这样我们就完全破解了这类游戏中状态性质的计算。
    上面讲了这么多,大家可能觉得比较难理解,那么我们就举个例子:
    S-Nim游戏(HDU1944):有L堆珠子,每堆珠子数量可能不同(最大可能为N=10000),双方轮流行动,每次行动从一堆珠子中取出若干颗,取出的珠子数量必须是一个正整数集合S中的一个数,若轮到某一方时不能按照规则行动,那么这一方判负,给出初始状态和集合S,问先手必胜还是先手必败。1L,|S|100
    很容易可以把S-Nim游戏转化为上述的组合游戏的模型,我们只需把每一堆珠子看做一个子游戏即可,注意到这些子游戏所转化成的有向图都是一样的,所以我们预处理出所有点的SG函数值,然后判断每一堆珠子数量对应的状态点的SG函数值异或起来是不是0即可。时间复杂度为O(|S|N)。需要代码的话请看这里
    以上就是我对SG函数的理解。

  • 相关阅读:
    android系统移植与驱动开发概述
    产品常用网址
    Java泛型、反射、集合、多线程
    Java常用类
    Java异常处理
    Java面向对象(二)
    Java面向对象(一)
    Java基础知识
    友链
    退役了
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793654.html
Copyright © 2011-2022 走看看