简体   繁体   English

三个数字的组合总计为1000

[英]Combinations for three numbers to sum up to 1000

I need every combination of three positive integers with the sum of 1000. 我需要三个正整数的每个组合,总和为1000。

This was my attempt but I'm unsure if this is correct since I have no way to validate it. 这是我的尝试,但我不确定这是否正确,因为我无法验证它。

def getSum():
    l = []
    for x in range(1, 999):
        total = 1000-x
        for y in range(1, 999):
            total = total-y
            if total>0:
                l.append([x, y, total])
    return l

print len(getSum())

I get 28776 different combinations. 我得到了28776种不同的组合。 Is that correct? 那是对的吗?

Since 1+998+1 and 1+1+998 are not the same thing, there are some incredible amount of combinations: 由于1+998+11+1+998 不是一回事,因此有一些令人难以置信的组合:

This line can generate them all: 这一行可以生成所有:

[(i, 1000-i-k, k) for i in range(1,999) for k in range(1,1000-i)]

Results: 结果:

[...
(1, 4, 995),
(1, 3, 996),
(1, 2, 997),
(1, 1, 998),
(2, 997, 1),
(2, 996, 2),
...]

The length of this list is: 这个清单的长度是:

498501

No, that number is not correct. 不,这个数字不正确。 The problem with your code is this line: 你的代码的问题是这一行:

        total = total-y

Here, you decrease total further and further with each value of y that you try, never resetting it to the value after just subtracting x . 在这里,您可以降低total越走越用的每个值y你尝试,它只是减去后从未重置价值x To fix it, create a new variable, eg total2 , and use that in the inner loop. 要修复它,请创建一个新变量,例如total2 ,并在内部循环中使用它。

        total2 = total-y

This way, you get 498501 combinations. 这样,您就获得了498501组合。 Also, you can break from the inner loop as soon as total2 < 0 . 此外,只要total2 < 0 ,就可以从内循环break


If you need just the number of combinations: Note that there are N-1 combinations to sum two numbers to N , eg for N==4 : 1+3 , 2+2 , 3+1 (assuming you consider 1+3 and 3+1 different). 如果你只需要组合的数量 :注意有N-1组合将两个数字相加到N ,例如对于N==41+3 2+2 3+1 (假设你考虑1+33+1不同)。 You can extend this to the case of three numbers as partitioning the number in two parts two times. 您可以将此扩展为三个数字的情况,将数字分为两部分两次。 This way, you only need a single loop. 这样,您只需要一个循环。 And this can be simplified further to an O(1) formula. 并且这可以进一步简化为O(1)公式。

Example, with naive approach using product as reference: 例如,使用product作为参考的天真方法:

>>> N = 100  # to make reference faster
>>> sum(1 for t in product(range(1, N+1), repeat=3) if sum(t)==N)
4851
>>> sum(N-1-i for i in range(1, N-1))
4851
>>> ((N-2)*(N-1))//2
4851

Of course, also works for N = 1000 (or much, much larger): 当然,也适用于N = 1000 (或更多,更大):

>>> N = 1000
>>> sum(N-1-i for i in range(1, N-1))
498501
>>> ((N-2)*(N-1))//2
498501

If you treated [1,1,998] and [1,998,1] the same (no unique integers): 如果你对[1,1,998]和[1,998,1]的处理方式相同(没有唯一的整数):

def getSum():
    l = []
    for x in range(1, 999):
        total = 1000-x
        for y in range(1, 999):
            total = total-y
            if total>0:
                z = [x, y, total]
                z.sort()
                if z not in l:
                    l.append(z)
return l

a = getSum()
print(len(a))

If you want 3 unique integers: 如果你想要3个唯一整数:

def getSum():
    l = []
    for x in range(1, 999):
        total = 1000-x
        for y in range(1, 999):
            total = total-y
            if total>0:
                z = [x, y, total]
                z.sort()
                if (z not in l) and (not((len(set(z)) < len(z)))):
                    l.append(z)
    return l

a = getSum()
print(len(a))

Otherwise your code is (in my sense) ok. 否则你的代码(在我看来)是好的。 I haven't check your answer yet... 我还没检查你的答案......

EDIT : I have checked it using brutal force. 编辑:我用残酷的力量检查了它。 The correct answer is actually 498501 if you treated (1,1,998) and (998,1,1) differently. 如果您对(1,1,998)和(998,1,1)的处理方式不同,那么正确的答案实际上是498501。 Currently I don't know why... 目前我不知道为什么......

Try this: 尝试这个:

def getSum():
    l = []
    for x in range(1, 6):
        for y in range(1, 6):
            total = 6-(y+x)
            if total>0:
                s = set([x, y, total])
                if s not in l:
                    l.append(s)
                    print(x, y, total)
    return l

print (len(getSum()))

This is my algorithm, Although there is better ways. 这是我的算法,虽然有更好的方法。 In this case I wrote code for number 6 and printed all combinations to show how it works. 在这种情况下,我编写了6号代码并打印了所有组合以显示它是如何工作的。 You can set 1000 or any number instead of 6 in this code(in 3 position) and ignore print() line. 您可以在此代码中设置1000或任何数字而不是6(在3位置)并忽略print()行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM