Python中的置换方法,带有一些固定元素

时间:2012-08-28 08:05:41

标签: python permutation restrictions

现在花了相当多的时间试图找到一种方法(我认为)应该是一个相对简单的程序,我已经设法编写了将产生结果的代码(感谢关于这个奇妙的建议)论坛!),但根据我的计算,计算所有可能性需要几年时间,所以我拼命寻找一些帮助,因为我担心我的计算机可能无法看到那天。 :)非常感谢任何输入!

我想要实现的是来自10个唯一条目的列表(例如['A','B','C','D','E','F','G',H' ,'我','J']),获得超过10的字符串长度的所有排列,但要求1个元素(例如'C')应该恰好发生3次,并且在所有可能的位置。< / p>

现在我正在使用:

options = ['A','B','C','D','E','F','G','H','I','J']
def combos(options,n):
    if (n <= 0): return
    for s in options:
        if len(s) <= n: yield s
        for t in combos(options,n-len(s)): yield s+t

for x in combos(options,10):
    if x.count("C") == 3 and len(x) == 10:
        print x

这样,它正在计算所有可能的排列,并选择具有3'Cs'的排列,因此产生大量不必要的排列,这些排列不包含3'Cs',因此为什么它需要的时间超过必要时间。有没有人有任何建议我如何让Python在生成排列时遵守3x'C'限制?

很多,非常感谢提前!

3 个答案:

答案 0 :(得分:4)

最简单的方法是使用其他字母生成7个元素的排列,然后将三个C插入其中。

答案 1 :(得分:4)

itertools是你的朋友:

from itertools import chain, imap, permutations, combinations, repeat
others = [o for o in options if o != 'C']
chain.from_iterable(permutations(*chain(repeat('C', 3), x))
                    for x in combinations(others, 7))

编辑:这会给出排列,而不是组合;如果您希望结果为AAAAAAACCC .. CCCJJJJJJJ,那么它必须略有不同。这是一个相当有效的产品/过滤解决方案:

from itertools import product
(x for x in product(options, repeat=10) if x.count('C') == 3)

这是使用BrenBarn建议的交错的方法:

from itertools import product
others = [o for o in options if o != 'C']
(r[:i] + ('C',) + r[i:j] + ('C',) + r[j:k] + ('C',) + r[k:]
 for r in product(others, repeat=7)
 for i in range(8) for j in range(i, 8) for k in range(j, 8))

你需要自己测试,但对我来说,交错方法要快得多。

答案 2 :(得分:1)

BrenBarn建议可以提供:

from itertools import product, combinations

otheroptions = ['A','B',   'D','E','F','G','H','I','J']
c = "C"
l = 10
nc = 3

for t in product(otheroptions, repeat=l-nc):
    for p in combinations(range(l), nc):
        r = list(t)
        for i in p:
            r[i:i] = [c]
        print "".join(r)