Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 组合对策_Algorithm_Combinatorics - Fatal编程技术网

Algorithm 组合对策

Algorithm 组合对策,algorithm,combinatorics,Algorithm,Combinatorics,游戏如下: 有一个由0和1组成的字符串,每个回合允许一个玩家 将一组连续的1转换为0。一个玩家最多可以转换k 连续的1到0,并且必须在his中将至少一个1转换为0 移动无法移动的玩家将失败 例如: 10100111(k=2) 在这里,获胜的移动将是:10100101(将最后第二个1转换为0) 这是一个2人的不偏不倚的游戏,我试着把它作为nim游戏的一个变体来分析。每个堆有n堆ai大理石(n组连续的1)。玩家最多可以从堆中任意位置移除k个弹珠,将一堆弹珠分成2堆。假设一个堆有5个弹珠(******

游戏如下:

有一个由0和1组成的字符串,每个回合允许一个玩家 将一组连续的1转换为0。一个玩家最多可以转换k 连续的1到0,并且必须在his中将至少一个1转换为0 移动无法移动的玩家将失败

例如:

10100111(k=2)

在这里,获胜的移动将是:10100101(将最后第二个1转换为0)

这是一个2人的不偏不倚的游戏,我试着把它作为nim游戏的一个变体来分析。每个堆有n堆ai大理石(n组连续的1)。玩家最多可以从堆中任意位置移除k个弹珠,将一堆弹珠分成2堆。假设一个堆有5个弹珠(
******
),您通过从位置2(
***
)移除k=2个弹珠来拆分堆。此外,如果您要移除第一个或最后一个k个大理石,堆不会分裂,只会将其大小减少k

这个模型能帮助找到原始游戏的策略吗?如果是,最佳策略是什么


任何帮助都将不胜感激

如前所述,游戏可以解决,每个位置都可以显示是赢(N位)还是输(p位)

考虑一下就足够了:

  • 初始丢失(p)位置为带
    n
    零的字符串

  • 胜利(N)位置是从某个位置移动到某个p位置的任何位置

  • p位置是指每次移动都会导致N位置的位置

因此,从初始位置开始,很容易找到每个位置的值,找到下一个N位置,从这些N位置找到(可能的)p位置

下面是解决此游戏的python代码:

from itertools import product
from collections import defaultdict

class Game(object):
    def __init__(self, n, k):
        self.n, self.k = n, k

    def states(self):              # All strings with 0|1 of length n
        return (''.join(x) for x in product(('0', '1'), repeat=self.n))

    def set_zeros(self, c, i, l):  # Set zeros in c from position i with length l
        return c[:i] + '0'*l + c[i+l:]

    def next_positions(self, c):   # All moves from given position
        for i in xrange(self.n):
            if c[i] == '1':        # First '1'
                yield self.set_zeros(c, i, 1)
                for j in xrange(1, self.k):
                    if i+j < self.n and c[i+j] == '1':
                        yield self.set_zeros(c, i, j+1)
                    else:
                        break

    def lost_positions(self):  # Initial lost position(s)
        return ['0'*self.n]

    def solve(self):
        next_pos = {}               # Maps position to posible positions after a move
        prev_pos = defaultdict(set) # Maps position to posible positions before that move
        win_lose = {}               # True - win/N-position, False - lose/P-position, None - not decided
        for s in self.states():
            win_lose[s] = None
            next_pos[s] = set(self.next_positions(s))
            for n in next_pos[s]:
                prev_pos[n].add(s)
        # Initial loses positions
        loses_to_check = set(self.lost_positions())
        for c in loses_to_check:
            win_lose[c] = False
        #
        while loses_to_check:
            lost_c = loses_to_check.pop()
            for w_pos in prev_pos[lost_c]:    # Winning moves
                if win_lose[w_pos] is None:
                    win_lose[w_pos] = True
                    for x in prev_pos[w_pos]: # Check positions before w_pos for P-position
                        if all(win_lose[i] for i in next_pos[x]):
                            win_lose[x] = False
                            loses_to_check.add(x)
        return win_lose

comb = '10100111'
g = Game(len(comb), 2)
win_lose = g.solve()
print comb, win_lose[comb]
来自itertools导入产品的

从集合导入defaultdict
班级游戏(对象):
定义初始化(self,n,k):
self.n,self.k=n,k
def状态(self):#长度为n的0 | 1的所有字符串
返回(“”.join(x)表示产品中的x(('0','1'),repeat=self.n))
def设置零点(self、c、i、l):#从位置i开始设置长度为l的c中的零点
返回c[:i]+'0'*l+c[i+l:]
def next_位置(自我,c):#从给定位置开始的所有移动
对于X范围内的i(self.n):
如果c[i]=“1”:#第一个“1”
屈服自置零(c,i,1)
对于X范围内的j(1,self.k):
如果i+j

注意:更改/覆盖方法
states()
next_positions(c)
lost_positions()
足以实现类似游戏的解算器。

你不能简单地将等效nim游戏(a-la sprague grundy)的获胜策略映射到你的游戏中。事实上,对于类似nim的游戏,我找不到很好的获胜策略。这就是我需要帮助的地方。这是。游戏解决了,一个完美的策略——对于任何位置——都很容易找到。@ypercube你以前遇到过这种游戏吗?如果是,你能给我一个资源的链接吗?我已经在维基百科页面上添加了一个关于尼姆的链接。该策略与Nim相同。找到一个导致“P位置”(先前玩家获胜)的移动,并进行游戏。无论对手玩什么(他有与尼姆相同的选项,再加上拆分选项中的一些选项),结果将是一个“N位置”(下一个玩家获胜),然后你将能够做同样的事情(找到一个导致P位置的移动)