【问题标题】:How can I Avoid Nested For-loop for choosing a combination?如何避免嵌套 For 循环来选择组合?
【发布时间】:2020-01-24 06:49:29
【问题描述】:

例如,有 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语句。
此外,如果我们不知道要考虑的属性数量,我们甚至无法使用此代码。
如上,还有更简单优雅的方法吗?

【问题讨论】:

  • 属性a_1, ..., a_M 应该存储在数组或列表等集合中。在这种情况下,您只需要两个循环
  • 感谢评论,但这个问题不仅仅是选择 a_1 之一并查看它。选择 (x for a_1, y for a_2, ..., z for a _M) (x, y, ..., z) 是一种选择。

标签: algorithm for-loop search combinations


【解决方案1】:

您的问题似乎与笛卡尔积有关。请注意,结果大小(组合数)为L1*L2*L3..*LM,其中Liai 的选择数

您可以使用递归或使用适当的库(如果可用)来实现它

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)

【讨论】:

  • 非常感谢。很抱歉出现了一些错误。我写了 M * N 个选项让你感到困惑。实际上,这里有 N ^ M 个选择。
  • 如果你有时间,你能解释一下我如何通过递归来实现这个炒锅吗?我想到了 DFS,但我无法设计具体的代码..
  • 我添加了递归和迭代实现。我对 Python 不是很熟悉,所以代码只是为了演示方法。
  • 感谢您的好意!
猜你喜欢
  • 2012-06-25
  • 2017-08-27
  • 2017-11-11
  • 2020-05-21
  • 2019-12-26
  • 1970-01-01
  • 2017-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多