是否有更有效的方法以10%的增量查找10个项目的所有组合?

时间:2012-03-29 07:44:31

标签: python loops combinations

我正在分析10种货币,我希望以10%的增量找到这些货币的所有可能组合。例如:

10% of A, 20% of B...etc 

约束如下:

总数必须达到100% 每种货币的数量可以在0%到100%之间,因此100%A的组合有效

目前我的代码看起来像这样:

for element in itertools.product(*curr_arr):
    if round(sum(element),1)==1:
        comb_input.append(list(element))

其中curr_arr本质上是一个数组,如下所示:

  [0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]

这种方法非常慢,因为它会查看所有组合,然后提取总和为1的组合。有没有更有效的方法来加快我的代码?

5 个答案:

答案 0 :(得分:5)

这很难看,但

combinations = []
for a in xrange(11):
    for b in xrange(11-a):
        for c in xrange(11-a-b):
            for d in xrange(11-a-b-c):
                for e in xrange(11-a-b-c-d):
                    for f in xrange(11-a-b-c-d-e):
                        for g in xrange(11-a-b-c-d-e-f):
                            for h in xrange(11-a-b-c-d-e-f-g):
                                for i in xrange(11-a-b-c-d-e-f-g-h):
                                    j = 10-a-b-c-d-e-f-g-h-i
                                    combinations.append((a,b,c,d,e,f,g,h,i,j))
print len(combinations)

这将在不到0.2秒的时间内为您提供所有92378组合。

请注意,它返回0到10之间的整数值,必须乘以10才能得到百分比。

答案 1 :(得分:2)

不是真的,你的问题基本上是Subset sum problem(给定一组整数,找到总和为k的那些)并且问题是NP-Complete。这意味着你找到比现在更好的算法的机会非常小。

我建议将这部分代码用C语言编写为Python扩展(参见Extending and Embedding the Python Interpreter)并从Python代码中调用该函数。这应该会给你一个不错的速度提升。

答案 2 :(得分:1)

如何找到100%的所有组合然后找到这些组合的所有排列?我无法运行你的例子,所以我不确定它在速度方面的比较。

import itertools

curr_arr = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

comb_input = [a for a in itertools.combinations_with_replacement(curr_arr, 10) if sum(a) == 100]
comb_input = [set(itertools.permutations(a)) for a in comb_input]

finish = []
for a in comb_input:
    finish += list(a)

print len(finish)

答案 3 :(得分:0)

for currencyA, currencyB, currencyC, currencyD, currencyE, currencyF, currencyG, currencyH, currencyI, currencyJ in itertools.permutations(range(0,101,10)):
    # you now have varying percentages of each currency
    # if sum of the currencies == 100
    # do whatever!

答案 4 :(得分:0)

可以直接生成总和为100%的组合,而无需过滤。使用my answer to a previous question

comb_input = [[x/10.0 for x in y] for y in lists_with_sum(10, 10)]