问题描述
我需要用 Python 编写一个脚本来解决这个任务,但我不知道该怎么做。
我有项目(让我们将它们命名为层):A、B、C...
每一层可以有任意数量的变化。
对于每个变体,给出了我们想要在输出中获得的百分比。
在输出时,我们必须根据给定的比例获得给定数量的所有层的唯一组合。
例如:
layers = [
{'A0':'30%','A1':'30%','A2':'40%'},{'B0':'10%','B1': '20%','B2' '40%','B3':'30%'},{'C0':'50%'}
]
如果我想获得 A、B、C 层变化的 10 种独特组合, 脚本应该像这样输出数据集:
[
('A0','B0'),('A0','B1','C0'),'B1'),('A1','B2','B2'),'B3',('A2','B3')
]
因此,每个层变化的计数应与给定的比例保持一致:
A0 = 3,A1 = 3,A2 = 4
B0 = 1,B1 = 2,B2 = 4,B3 = 3,C0 = 5
如果我们想要获得 20 个变体,则计数会有所不同:
A0 = 6,A1 = 6,A2 = 8
B0 = 2,B1 = 4,B2 = 8,B3 = 6,C0 = 10
它应该适用于任意数量的层、变化、比例并获得输出组合的准确计数 (或组合的最大值,如果没有更多组合来获得确切数量)
解决方法
对于每一层,你可以找到分布列表,然后递归地合并结果以产生组合。由于 pid = spawn(fn -> 1 + 2 end)
#=> #PID<0.118.0>
Process.monitor(pid)
#=> #Reference<0.906660723.3006791681.40191>
Process.exit(pid,:kill)
#=> true
receive do
msg -> msg
end
#=> {:DOWN,#Reference<0.906660723.3006791681.40191>,:process,#PID<0.118.0>,:noproc}
可能产生大量组合,后者是一个生成器,您可以使用 get_combos
按需生成值:
next
输出:
import itertools
layers = [{'A0': '30%','A1': '30%','A2': '40%'},{'B0': '10%','B1': '20%','B2': '40%','B3': '30%'},{'C0': '50%'}]
def layer_combos(l,d):
return [i for a,b in l.items() for i in ([a]*int((d*(int(b[:-1])/float(100)))))]
def get_offsets(l,d,c = []):
if not d:
yield tuple(c)
else:
if l:
yield from get_offsets(l[1:],d-1,c+[l[0]])
if not c or c[-1] is not None:
for i in range(d - len(l)):
yield from get_offsets(l,d-(i+1),c+([None]*(i+1)))
def get_combos(l,c = []):
if not l:
if len((l:=[tuple(list(filter(None,i))) for i in zip(*c)])) == len(set(l)):
yield l
else:
for i in itertools.permutations((l1:=layer_combos(l[0],d)),(l2:=len(l1))):
for j in set(get_offsets(i,d)):
yield from get_combos(l[1:],c + [j])
result = get_combos(layers,10)
for _ in range(10): #first ten combinations
print(next(result))