[目标是获得分发列表,这些列表允许例如通过对具有不同熟悉权重的变量进行加权来测试场景,这些总和等于100(因此可以与百分比相结合)。
我在下面提出的方法有效,但可能不是最佳方法。随时提出任何改进建议。
将整数合成为n个部分的函数:
def comppercents(n):
y = [0] * n
y[0] = 100
while True:
yield(y)
v = y[-1]
if (100 ==v ):
break
y[-1] = 0
j = -2
while (0==y[j]):
j -= 1
y[j] -= 10
y[j+1] = 10 + v
for x in comppercents(3):
print(x)
[100, 0, 0]
[90, 10, 0]
[90, 0, 10]
[80, 20, 0]
...
[0, 20, 80]
[0, 10, 90]
[0, 0, 100]
(66个变体)
from itertools import groupby
def comb_100(n):
global L_combination_100
L_combination_100= []
# adds in L_combination_100 all the possible lists (without the order mattering) whose sum of the elements is 10
find_raw_combination([i+1 for i in list(range(10))]*10,10)
# we remove all duplicate lists
for i in range(len(L_combination_100)):
L_combination_100[i].sort()
L_combination_100.sort()
L_combination_100 = list(k for k,_ in groupby(L_combination_100)) # groupby from itertools
# We remove all lists that have too many elements (> n)
L_combination_100 = [i if len(i)<=n else [] for i in L_combination_100]
L_combination_100 = [x for x in L_combination_100 if x != []]
# We add 0's to lists that don't have n items
# All items within each list are multiplied by 10 to obtain a sum equal to 100
for i,l in enumerate(L_combination_100) :
if len(l) != n:
L_combination_100[i].extend([0]*(n-len(l)))
L_combination_100[i] = [ii*10 for ii in L_combination_100[i]]
#That's how we got our final list of lists/combinations. We have to be careful that the order doesn't matter in these lists.
return L_combination_100
#Strongly inspired from https://stackoverflow.com/questions/4632322/finding-all-possible-combinations-of-numbers-to-reach-a-given-sum
def find_raw_combination(numbers, target, partial=[]): # need global variable L_combination_100
s = sum(partial)
# check if the partial sum is equals to target
if s == target:
L_combination_100.append(partial) if partial not in L_combination_100 else L_combination_100
if s >= target:
return # reach if we get the number
for i in range(len(numbers)):
n = numbers[i]
remaining = numbers[i+1:]
find_raw_combination(remaining, target, partial + [n])
示例:
comb_100(3)
输出:
[[10, 10, 80],
[10, 20, 70],
[10, 30, 60],
[10, 40, 50],
[10, 90, 0],
[20, 20, 60],
[20, 30, 50],
[20, 40, 40],
[20, 80, 0],
[30, 30, 40],
[30, 70, 0],
[40, 60, 0],
[50, 50, 0],
[100, 0, 0]]