搜索可迭代链组合的最快方法?

时间:2013-11-19 01:01:07

标签: python search iterator set combinations

我能找到10k及以上整数的幂集之和的最快方法是什么?

long_list = [randrange(0,10000) for r in xrange(10000)]

desired_sum = sum(randint(0,10000)+randint(0,10000)+randint(0,10000))

def powerset(iterable):
    # notice the '3' in combinations(s,3), taking all combinations of 3. 
    s = list(iterable)
    return chain.from_iterable(combinations(s, 3) for r in range(len(s)+1))

ps = powerset(set(long_list))

if desired_sum > 29994:
    print "cannot compute"
else:
    for i in ps:
        if sum(i) == desired_sum: # last combination of chain 9999+9998+9997
            print i

我的电脑计算需要很长时间,而且我想问一些关于如何处理像这样的大型组合的技巧。

为了像这样搜索,我的for循环必须耗尽整个列表,然后才能细化组合的总和。

3 个答案:

答案 0 :(得分:3)

找到最快的解决方案。

from random import randrange
long_list = [randrange(0,10000) for r in xrange(10000)]

def main():
    myList, result = sorted(set(long_list), reverse = True), []
    myLen = len(myList)
    for i in xrange(myLen):
        for j in xrange(i + 1, myLen):
            if 29994 - (myList[i] + myList[j]) > myList[j]: break
            for k in xrange(j + 1, myLen):
                tsum = myList[i] + myList[j] + myList[k]
                if tsum < 29994:
                    break
                elif tsum == 29994:
                    result.append((myList[i], myList[j], myList[k]))
    print result
    return result

import cProfile
cProfile.run("main()")

这在我的机器上运行一秒钟。这个解决方案的优点在于,这可以通过递归来推广任意数量的与总和相匹配的项目。

答案 1 :(得分:2)

如果您知道所需的总和,则只需迭代所有combinations(s, 2)),并测试缺少的元素是否在集合中

感谢@thefourtheye

from random import randrange
from itertools import combinations
long_list = [randrange(0,10000) for r in xrange(10000)]

def powerset(it):
    return [(i[0], i[1], 29994 - sum(i)) for i in combinations(it, 2) if 29994 - sum(i) in it]

def main():
    print powerset(set(long_list))

import cProfile
cProfile.run("main()")

答案 2 :(得分:1)

这个genexpr:

(combinations(s, 3) for r in range(len(s)+1))

...只是反复生成相同的组合,len(s)次。那不是一个特权。更重要的是,这只是浪费精力;如果所有组合都不匹配,则这些组合的各个副本中的任何组合都不匹配。

因此,您可以通过不添加额外的工作进行优化:

def powerset(iterable):
    return combinations(iterable, 3)

由于您的iterable预计会有大约6300名成员(这是您在10000列表中应该有多少唯一值,因此调用set然后list将为您提供一个列表那么长,这将使事情快大约6300倍。