如何返回所有可能的条件二分匹配?

时间:2019-04-11 21:48:10

标签: python recursion permutation matching

假设我们有一个长度为X = (x_1, ..., x_N)的数组N。我们要返回长度为M(固定的M)的所有可能的数组,它们的元素可以来自(x_1, ..., x_N, NaN),这样每个x_i最多使用一次,而{ {1}}顺序被保留。例如,如果x_iN = 3,则一些可能的向量是

M = 7

但是以下向量是不可接受的:

 Z = (x_1, NaN, NaN, x_2, x_3, NaN, NaN)
 Z = (NaN, x_1, NaN, NaN, x_3, NaN, NaN)
 Z = (x_3, NaN, NaN, NaN, NaN, NaN, NaN)
 Z = (NaN, NaN, NaN, NaN, NaN, NaN, NaN)

此问题可以看作是将某些 Z = (x_1, x_1, NaN, x_2, x_3, NaN, NaN) Z = (NaN, x_3, NaN, NaN, x_2, NaN, NaN) 与位置x_i匹配,从而保留了1,...,M的顺序。我怎样才能做到这一点?我当时在考虑使用递归函数x_i,该函数在每个可能的点(f(X, M))上剪切向量Z,然后将for i in range(1,M+1)(定义为基本情况)与{ {1}}(递归)。但是这种方法不能提供唯一的向量,因此我必须在以后删除重复项,而且效率不高。有没有更好的方法来解决这个问题?也许使用itertools?

1 个答案:

答案 0 :(得分:0)

我认为类似的东西应该对您有用。从列表M中获取元素基本上是对X框的迭代填充。在这种情况下,默认内容为None,但是您应该可以进行调整。您可以see how it works on repl

N = 3
M = 6

X = range(N) # or example, can be [x1,x2,x3]

for j1 in range(M-N+1):
  for j2 in range(j1+1,M-N+2):
    for j3 in range(j2+1,M):
      r = [None]*M
      r[j1] = X[0]
      r[j2] = X[1]
      r[j3] = X[2]
      print(r)

这将产生以下输出:

[0, 1, 2, None, None, None]
[0, 1, None, 2, None, None]
[0, 1, None, None, 2, None]
[0, 1, None, None, None, 2]
[0, None, 1, 2, None, None]
[0, None, 1, None, 2, None]
[0, None, 1, None, None, 2]
[0, None, None, 1, 2, None]
[0, None, None, 1, None, 2]
[0, None, None, None, 1, 2]
[None, 0, 1, 2, None, None]
[None, 0, 1, None, 2, None]
[None, 0, 1, None, None, 2]
[None, 0, None, 1, 2, None]
[None, 0, None, 1, None, 2]
[None, 0, None, None, 1, 2]
[None, None, 0, 1, 2, None]
[None, None, 0, 1, None, 2]
[None, None, 0, None, 1, 2]
[None, None, None, 0, 1, 2]

理想情况下,您希望将其推广为任意N,这样就不必对j1j2j3索引进行硬编码。