首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Y标记桶中x标记球的Python迭代器

Y标记桶中x标记球的Python迭代器
EN

Stack Overflow用户
提问于 2018-09-08 00:06:10
回答 1查看 344关注 0票数 1

我需要Python迭代器来生成Y标记桶中X标记球的所有组合,其中X大于或等于Y,而且所有桶都包含一个或多个球。

对于X=4和Y=3的情况,球标记为labeled,桶标记为1-2-3,一些可能的组合如下:

第1桶: A,B

第2桶:C

第3桶:d

第1桶:a

第2桶: C,B

第3桶:d

第1桶:a

第2桶:C

第3桶: D,B

第1桶: A,C

第2桶:B

第3桶:d

..。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-08 23:28:15

AR对最初问题的评论帮助找到了答案,除了“X的所有Y-分区”之外,我需要的是“X的所有Y-分区的所有排列”。Knuth algorithm here是Python2实现的“X的所有Y分区”。我需要为此创建Python3实现(通过将所有xrangerange交换),然后将函数包装在一个新生成器中,该生成器在每次迭代时应用itertools.permutations。下面的代码就是结果。

代码语言:javascript
运行
复制
def algorithm_u(ns, m):
    """
    - Python 3 implementation of
        Knuth in the Art of Computer Programming, Volume 4, Fascicle 3B, Algorithm U
    - copied from Python 2 implementation of the same at
        https://codereview.stackexchange.com/questions/1526/finding-all-k-subset-partitions
    - the algorithm returns
        all set partitions with a given number of blocks, as a python generator object

    e.g.
        In [1]: gen = algorithm_u(['A', 'B', 'C'], 2)

        In [2]: list(gen)
        Out[2]: [[['A', 'B'], ['C']],
                  [['A'], ['B', 'C']],
                  [['A', 'C'], ['B']]]
    """

    def visit(n, a):
        ps = [[] for i in range(m)]
        for j in range(n):
            ps[a[j + 1]].append(ns[j])
        return ps

    def f(mu, nu, sigma, n, a):
        if mu == 2:
            yield visit(n, a)
        else:
            for v in f(mu - 1, nu - 1, (mu + sigma) % 2, n, a):
                yield v
        if nu == mu + 1:
            a[mu] = mu - 1
            yield visit(n, a)
            while a[nu] > 0:
                a[nu] = a[nu] - 1
                yield visit(n, a)
        elif nu > mu + 1:
            if (mu + sigma) % 2 == 1:
                a[nu - 1] = mu - 1
            else:
                a[mu] = mu - 1
            if (a[nu] + sigma) % 2 == 1:
                for v in b(mu, nu - 1, 0, n, a):
                    yield v
            else:
                for v in f(mu, nu - 1, 0, n, a):
                    yield v
            while a[nu] > 0:
                a[nu] = a[nu] - 1
                if (a[nu] + sigma) % 2 == 1:
                    for v in b(mu, nu - 1, 0, n, a):
                        yield v
                else:
                    for v in f(mu, nu - 1, 0, n, a):
                        yield v

    def b(mu, nu, sigma, n, a):
        if nu == mu + 1:
            while a[nu] < mu - 1:
                yield visit(n, a)
                a[nu] = a[nu] + 1
            yield visit(n, a)
            a[mu] = 0
        elif nu > mu + 1:
            if (a[nu] + sigma) % 2 == 1:
                for v in f(mu, nu - 1, 0, n, a):
                    yield v
            else:
                for v in b(mu, nu - 1, 0, n, a):
                    yield v
            while a[nu] < mu - 1:
                a[nu] = a[nu] + 1
                if (a[nu] + sigma) % 2 == 1:
                    for v in f(mu, nu - 1, 0, n, a):
                        yield v
                else:
                    for v in b(mu, nu - 1, 0, n, a):
                        yield v
            if (mu + sigma) % 2 == 1:
                a[nu - 1] = 0
            else:
                a[mu] = 0
        if mu == 2:
            yield visit(n, a)
        else:
            for v in b(mu - 1, nu - 1, (mu + sigma) % 2, n, a):
                yield v

    n = len(ns)
    a = [0] * (n + 1)
    for j in range(1, m + 1):
        a[n - m + j] = j - 1
    return f(m, n, 0, n, a)

class algorithm_u_permutations:
    """
    generator for all permutations of all set partitions with a given number of blocks
    e.g.
        In [4]: gen = algorithm_u_permutations(['A', 'B', 'C'], 2)

        In [5]: list(gen)
        Out[5]:
        [(['A', 'B'], ['C']),
         (['C'], ['A', 'B']),
         (['A'], ['B', 'C']),
         (['B', 'C'], ['A']),
         (['A', 'C'], ['B']),
         (['B'], ['A', 'C'])]
    """

    from itertools import permutations

    def __init__(self, ns, m):

        self.au = algorithm_u(ns, m)
        self.perms = self.permutations(next(self.au))

    def __next__(self):

        try:
            return next(self.perms)

        except StopIteration:
            self.perms = self.permutations(next(self.au))
            return next(self.perms)

    def __iter__(self):
        return self
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52230899

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档