例如,有 M个属性 a_1,...,a_M 可供选择,并且每个属性具有N个选择。
问题是搜索N ^ M个选择的整个组合。
使用嵌套的for循环,伪代码如下所示。
# length of a_1, ..., a_M is N for each.
for c_1 in a_1:
for c_2 in a_2:
...
for c_M in a_M:
evaluate(c_1, c_2, ..., c_M)
但是,这种极端嵌套的for循环看起来很差,我不想写M遍for语句。
另外,如果我们不知道要考虑的属性数量,我们甚至无法使用此代码。
还有其他更简单,更优雅的方法吗?
答案 0 :(得分:1)
您的问题似乎与笛卡尔积有关。请注意,结果大小(组合数)为L1*L2*L3..*LM
,其中Li
是ai
的选择数
您可以使用递归来实现它,或者使用适当的库(如果有)
Python示例:
import itertools
l = [['a', 'b'], [1, 2, 3], [False, True]]
print([list(a) for a in itertools.product(*l)])
>>> [['a', 1, False], ['a', 1, True], ['a', 2, False], ['a', 2, True],
['a', 3, False], ['a', 3, True], ['b', 1, False], ['b', 1, True],
['b', 2, False], ['b', 2, True], ['b', 3, False], ['b', 3, True]]
递归和迭代实现的示例:
def product_rec(a, fromindex, res):
if fromindex == len(a):
print(res)
return
for x in a[fromindex]:
product_rec(a, fromindex+1, res+[x])
def product_iter(a):
NN = 1
for x in a:
NN *= len(x) #number of combinations
b = [[0]*len(a) for i in range(NN)]
N = NN
M = 1
for k in range(len(a)):
N //= len(a[k])
c = 0
for l in range(M):
for i in range(len(a[k])):
for j in range(N):
b[c][k] = a[k][i]
c += 1
M *= len(a[k])
print(b)
l = [['a', 'b'], [1, 2, 3], [False, True]]
product_rec(l, 0, [])
product_iter(l)