【问题标题】:Fastest way for the computer to find combinations of non-negative integers x_1<=x_2<=...<= x_n and sum to 100计算机查找非负整数 x_1<=x_2<=...<= x_n 和总和为 100 的最快方法
【发布时间】:2018-02-11 05:51:04
【问题描述】:

我想为计算机找到一种有效的方法来处理执行以下操作的大量变量(例如 50:x1、...、x50): 找到所有组合 [x1,x2,x3] 满意:

  1. 0

  2. x1 + x2 + x3 = 100

这是一个查找 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。

普通循环不太可能做到这一点

【问题讨论】:

  • “大数”有多少?
  • 您能想出一种更快的方法来为给定的i 找到j,例如i + j == 100
  • @avigil:这个问题没有那个问题那么难。 (这与 {1, ..., 100} 的子集无关。)
  • 你可以试试list(itertools.chain(*[((i,100-i),(100-i,i)) if i!=100-i else ((i,i),) for i in range(51)]))

标签: python loops optimization combinations integer-partition


【解决方案1】:

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

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 产生与上面相同的输出

【讨论】:

    【解决方案2】:

    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),
    

    【讨论】:

    • 您的代码不起作用...您可以复制粘贴并自己尝试
    • 我想你的意思是list(filter(lambda x: x is not None, alist))
    • 你用的是哪个版本的python??
    • @avigil 是或无论如何从列表中删除 None 值
    • 如果输入未按升序排序,则会出现问题,因为例如combinations(range(100,0, -1), 3) 会抛出所有可能的答案
    猜你喜欢
    • 2018-01-10
    • 1970-01-01
    • 2010-10-22
    • 2019-11-21
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多