一组整数和一个数n 称为partition 的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 数字至少为1。
这是一种相当有效的方法来生成给定整数的所有分区。请注意,这些是有序的;如果你想从这些分区产生随机组合,你可以使用random.shuffle。
我们首先打印大小为 5 的 16 个分区,然后我们计算大小为 7 的 40 个分区的数量 (= 2738)。
此代码源自Jerome Kelleher 的算法。
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)))
输出
[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