计算机查找非负整数组合的最快方法x_1< = x_2< = ...< = x_n,总和为100

时间:2018-02-11 05:51:04

标签: python loops optimization combinations integer-partition

我想找到一种有效的方法让计算机处理大量的变量(例如50:x1,...,x50),它们会做这样的事情: 找到所有组合[x1,x2,x3] 满足:

  1. 0< = x1< = x2< = x3

  2. x1 + x2 + x3 = 100

  3. 以下是查找sum = 100的所有组合的示例,但[1,99]和[99,1]在此处被视为不同:

    x=[]
    for i, j in itertools.product(range(0,101), range(0,101)):
        if i+j==100:
           x.append([i,j])
    

    我想找到一种减少循环次数的方法,只给出类似的东西:

    [0,100],[1,99],[2,98],..........,[50,50]

    而[51,49]没有。

    主要目标是使用50个变量(x_1,... x_50)进行此操作,总计最多100个。

    使用正常循环

    不太可能

2 个答案:

答案 0 :(得分:1)

对于形式为i+j+k==100的3个变量,我们需要两个for循环,对于n个变量,我们需要n-1个循环来产生结果

for i in range(0,101):
    for j in range(i,101):
        if(100-j-i>=j):
            print i,j,100-j-i

结果

0 0 100
0 1 99
0 2 98
0 3 97
0 4 96
0 5 95
......
......
32 33 35
32 34 34
33 33 34

修改1

或者如果你不想编写n-1循环的代码,请使用这个反复函数,它会更快,因为我做了一些优化来减少它的运行时间

def foo(numberofvariables,sumofvar):
    templist=[0]*(numberofvariables)

    def fun(depthofrecursion,tempsum,sumofvar,var):

        if(depthofrecursion<numberofvariables-1):
            for i in range(var,(sumofvar/(numberofvariables-depthofrecursion)+2)):

                templist[depthofrecursion]=i;
                fun(depthofrecursion+1,tempsum+i,sumofvar,i)
        else:

            if(sumofvar-tempsum>=var):
                templist[numberofvariables-1]=sumofvar-tempsum
                for i in range(0,numberofvariables):
                    print templist[i],

                print 

    fun(0,0,sumofvar,0)

foo(3,100)

这里n是3(变量数),sum是100产生与上面相同的输出

答案 1 :(得分:1)

combinaison ??

怎么样?
import random
from itertools import combinations
l = random.sample(range(1, 10000), 100)

alist =[(x1,x2,x3) if  (0 <= x1 <= x2 <= x3 and sum([x1,x2,x3]) == 100) else None for x1,x2,x3 in combinations(sorted(l), 3)]
L = list(filter(None, alist))

输出

[(1, 4, 95),
 (1, 7, 92),
 (1, 10, 89),
 (1, 12, 87),
 (1, 17, 82),
 (1, 18, 81),
 (1, 30, 69),
 (1, 32, 67),
 (1, 34, 65),
 (1, 38, 61),
 (1, 49, 50),
 (2, 3, 95),
 (2, 5, 93),
 (2, 7, 91),
 (2, 10, 88),
 (2, 12, 86),
 (2, 17, 81),
 (2, 18, 80),
 (2, 22, 76),
 (2, 30, 68),
 (2, 33, 65),
 (3, 4, 93),
 (3, 5, 92),
 (3, 7, 90),
 (3, 10, 87),
 (3, 12, 85),
 (3, 17, 80),