我使用randint(30,60)
获得了30-60范围内的随机int。让我们说它是40.我想把这个数字分成7个随机整数。因此,例如[5,5,5,5,5,5,10]
是有效的结果。但是有很多可能的解决方案,例如[6,6,6,6,6,6,4]
或[4,2,9,13,8,1,3]
......
我知道有很多解决方案,但我正在寻找一种快速的方法来解决它们。我不是试图获得每一个解决方案,而是寻找一种快速的方法来在短时间内迭代它们。实现它的一种方法是随机选择一个数字(让我们说在1-15的范围内)并将其保存到列表中,然后执行一个while循环,直到总和恰好为40.我试过它并且它根本没有效率。我认为选择[5,5,5,5,5,5,10]
这样的起始值并以"1st digit -2"
和3rd +2
等精确方式更改数字以获得[3,5,7,5,5,5,10]
将是一个更快的解决方案。有谁知道怎么做或有一个很好的建议?谢谢。我更喜欢python 3。
答案 0 :(得分:4)
一组总和为n
的整数称为n
import random
def random_partition(n, size):
seq = []
while size > 1:
x = random.randint(1, 1 + n - size)
seq.append(x)
n -= x
size -= 1
seq.append(n)
return seq
n = 40
for _ in range(20):
print(random_partition(n, 7))
;如果订单很重要,那么它就被称为组合。
这是制作随机成分的一种相当快速的方法。
[26, 2, 8, 1, 1, 1, 1]
[30, 2, 1, 3, 1, 1, 2]
[26, 5, 3, 1, 2, 2, 1]
[2, 25, 9, 1, 1, 1, 1]
[28, 2, 2, 2, 1, 2, 3]
[23, 1, 9, 3, 2, 1, 1]
[3, 26, 1, 7, 1, 1, 1]
[25, 1, 7, 1, 2, 1, 3]
[10, 8, 11, 5, 3, 1, 2]
[19, 16, 1, 1, 1, 1, 1]
[12, 23, 1, 1, 1, 1, 1]
[1, 14, 15, 7, 1, 1, 1]
[29, 5, 1, 1, 2, 1, 1]
[25, 1, 3, 3, 1, 2, 5]
[10, 12, 10, 4, 1, 2, 1]
[13, 4, 6, 14, 1, 1, 1]
[31, 3, 1, 1, 1, 1, 2]
[16, 11, 9, 1, 1, 1, 1]
[3, 26, 5, 3, 1, 1, 1]
[31, 2, 1, 2, 2, 1, 1]
典型输出
1 + n - size
我们使用size - 1
作为上限,因为其他random.shuffle
数字至少为1。
这是生成给定整数的所有分区的一种相当有效的方法。请注意,这些都是有序的;如果要从这些分区生成随机组合,可以使用def partitionR(num, size):
a = [0, num] + [0] * (num - 1)
size -= 1
k = 1
while k > 0:
x = a[k - 1] + 1
y = a[k] - 1
k -= 1
while x <= y and k < size:
a[k] = x
y -= x
k += 1
a[k] = x + y
if k == size:
yield a[:k + 1]
for u in partitionR(16, 5):
print(u)
print('- ' * 32)
print(sum(1 for _ in partitionR(40, 7)))
。
我们首先打印大小为5的16的所有分区,然后计算大小为7(= 2738)的40分区数。
此代码源自partition的算法。
[1, 1, 1, 1, 12]
[1, 1, 1, 2, 11]
[1, 1, 1, 3, 10]
[1, 1, 1, 4, 9]
[1, 1, 1, 5, 8]
[1, 1, 1, 6, 7]
[1, 1, 2, 2, 10]
[1, 1, 2, 3, 9]
[1, 1, 2, 4, 8]
[1, 1, 2, 5, 7]
[1, 1, 2, 6, 6]
[1, 1, 3, 3, 8]
[1, 1, 3, 4, 7]
[1, 1, 3, 5, 6]
[1, 1, 4, 4, 6]
[1, 1, 4, 5, 5]
[1, 2, 2, 2, 9]
[1, 2, 2, 3, 8]
[1, 2, 2, 4, 7]
[1, 2, 2, 5, 6]
[1, 2, 3, 3, 7]
[1, 2, 3, 4, 6]
[1, 2, 3, 5, 5]
[1, 2, 4, 4, 5]
[1, 3, 3, 3, 6]
[1, 3, 3, 4, 5]
[1, 3, 4, 4, 4]
[2, 2, 2, 2, 8]
[2, 2, 2, 3, 7]
[2, 2, 2, 4, 6]
[2, 2, 2, 5, 5]
[2, 2, 3, 3, 6]
[2, 2, 3, 4, 5]
[2, 2, 4, 4, 4]
[2, 3, 3, 3, 5]
[2, 3, 3, 4, 4]
[3, 3, 3, 3, 4]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2738
<强>输出强>
SKPhysicsBody(bodies:[SKPhysicsBody])
答案 1 :(得分:2)
如果你只关心获得一组任意数字加起来而不是通过所有组合进行详尽的迭代,以下内容应该可以帮到你需要。
def get_parts(total, num_parts=7, max_part=15):
running_total = 0
for i in range(num_parts - 1):
remaining_total = total - running_total
upper_limit = min(max_part, remaining_total - num_parts + 1 + i)
# need to make sure there will be enough left
lower_limit = max(1, remaining_total - max_part*(num_parts - i - 1))
part = randint(lower_limit, upper_limit)
running_total += part
yield part
yield total - running_total
>>> list(get_parts(40))
[2, 7, 10, 11, 1, 4, 5]
>>> list(get_parts(40))
[7, 13, 11, 6, 1, 1, 1]
>>> list(get_parts(50, 4))
[6, 14, 15, 15]
当然,上面每个列表中的项目并不是真正随机的,并且会支持列表中较早的较大数字以及稍后较小的数字。如果你想要更多的伪随机元素,可以通过random.shuffle()提供这些列表。
答案 2 :(得分:1)
来自Python Integer Partitioning with given k partitions
def partitionfunc(n,k,l=1):
'''n is the integer to partition, k is the length of partitions, l is the min partition element size'''
if k < 1:
raise StopIteration
if k == 1:
if n >= l:
yield (n,)
raise StopIteration
for i in range(l,n//k+1):
for result in partitionfunc(n-i,k-1,i):
yield (i,)+result
list(partitionfunc(40,7))
答案 3 :(得分:0)
您可以对前6个值的所有可能组合(其中总和不超过40)进行简单迭代,并计算第7个值。
for a in range(41):
for b in range(41-a):
for c in range(41-(a+b)):
for d in range(41-(a+b+c)):
for e in range(41-(a+b+c+d)):
for f in range(41-(a+b+c+d+e)):
g = 40 - (a+b+c+d+e+f)
# Do what you need to do here
通过预先计算总和,您可以将循环所需的时间减少一半(根据使用timeit
的测试):
for a in range(41):
for b in range(41-a):
ab = a + b
for c in range(41-ab):
abc = ab + c
for d in range(41-abc):
abcd = abc + d
for e in range(41-abcd):
abcde = abcd + e
for f in range(41-abcde):
g = 40 - (abcde + f)
# Do what you need to do here