python – 生成生成集的算法

给出这个输入:[1,2,3,4]

我想生成一组跨越集:

[1] [2] [3] [4]
[1] [2] [3,4]
[1] [2,3] [4]
[1] [3] [2,4]
[1,2] [3] [4]
[1,3] [2] [4]
[1,4] [2] [3]
[1,2] [3,4]
[1,3] [2,4]
[1,4] [2,3]
[1,2,3] [4]
[1,2,4] [3]
[1,3,4] [2]
[2,3,4] [1]
[1,2,3,4]

每个集合都具有原始集合的所有元素,被排列成独特的子集.生成这些集合的算法是什么?我使用选择,排列,组合,电源设置等尝试Python生成器函数,但无法获得正确的组合.

20 Jan 2009

这不是一个家庭作业的问题.这是一个改进的答案,我正在为www.projecteuler.net问题#118.我已经有一个缓慢的解决方案,但提出了一个更好的方法 – 除了我无法弄清楚如何做跨越集.

当我从就职典礼回来时,我会发布我的代码.

21 Jan 2009

这是我使用的最终算法:

def spanningsets(items):
    if len(items) == 1:
        yield [items]
    else:
        left_set, last = items[:-1], [items[-1]]
        for cc in spanningsets(left_set):
            yield cc + [last]
            for i,elem in enumerate(cc):
                yield cc[:i] + [elem + last] + cc[i+1:]

@Yuval F:我知道如何做一个电源.这是一个简单的实现:

def powerset(s) :
    length = len(s)
    for i in xrange(0, 2**length) :
        yield [c for j, c in enumerate(s) if (1 << j) & i]
    return
最佳答案
这应该是有效的,尽管我还没有测试.

def spanningsets(items):
    if not items: return
    if len(items) == 1:
        yield [[items[-1]]]
    else:
        for cc in spanningsets(items[:-1]):
            yield cc + [[items[-1]]]
            for i in range(len(cc)):
                yield cc[:i] + [cc[i] + [items[-1]]] + cc[i+1:]

for sset in spanningsets([1, 2, 3, 4]):
    print ' '.join(map(str, sset))

输出:

[1] [2] [3] [4]
[1, 4] [2] [3]
[1] [2, 4] [3]
[1] [2] [3, 4]
[1, 3] [2] [4]
[1, 3, 4] [2]
[1, 3] [2, 4]
[1] [2, 3] [4]
[1, 4] [2, 3]
[1] [2, 3, 4]
[1, 2] [3] [4]
[1, 2, 4] [3]
[1, 2] [3, 4]
[1, 2, 3] [4]
[1, 2, 3, 4]

转载注明原文:python – 生成生成集的算法 - 代码日志