我能找到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循环必须耗尽整个列表,然后才能细化组合的总和。
答案 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倍。