【问题标题】:Python generate all possible combinations of matrixPython生成矩阵的所有可能组合
【发布时间】:2019-02-28 10:50:07
【问题描述】:

我需要在 Python 中生成矩阵的所有组合。输入将是两个整数 n 和 m,我需要以 1 和 0 作为可能值来生成该矩阵的所有可能状态。

例如:

n = 3 m = 2
[[0 0 0] [1 0 0] [1 1 0]
 [0 0 0] [0 0 0] [0 0 0]
 [0 0 0],[0 0 0],[0 0 0] . . . . .
]

考虑到在运行时之前我不会知道 n 和 m 的值,是否有一种干净有效的方法来执行此操作?使用的最大值将是 n = 16 m = 16。

【问题讨论】:

  • 会有 2^(nm) 输出。没有更快的方法来枚举它们中的每一个。另外,你试过什么?
  • 可能值得询问您是否需要这些矩阵,或者它们是否是其他东西的中间状态。如果是后者,你可以这样优化它
  • 抱歉,整数是行和列。直到现在我知道运行前的值,所以只是使用两个嵌套循环,但这不再可行

标签: python list math combinations


【解决方案1】:

一种方法是在列表推导中生成所有长度为m*n 的二进制序列,并在每次迭代时将它们重塑为(m,n) 形状的嵌套列表。

生成所有序列的一种简单方法是将01 的笛卡尔积与n*m 重复,这将产生2^(m*n) 组合:

from itertools import product
m=3
n=3

x = [[list(i[x:x+m]) for x in range(0, len(i), m)] for i in product("01", repeat=m*n)]

输出

[[['0' '0' '0']
  ['0' '0' '0']
  ['0' '0' '0']]

 [['0' '0' '0']
  ['0' '0' '0']
  ['0' '0' '1']]

 [['0' '0' '0']
  ['0' '0' '0']
  ['0' '1' '0']]
 ...

print(len(x))
# 512

【讨论】:

    【解决方案2】:

    如果您想同时获得所有矩阵,只需使用 itertools.productnumpy.reshape 它们生成平面列表:

    from itertools import product
    import numpy as np
    
    n, m = 2, 2
    
    x = product([1, 0], repeat=n*m)
    x = np.reshape(list(x), (-1, n, m))
    print(x)
    

    输出为 2x2:

    array([[[1, 1],
            [1, 1]],
    
           [[1, 1],
            [1, 0]],
    
           [[1, 1],
            [0, 1]],
    
           [[1, 1],
            [0, 0]],
    
           [[1, 0],
            [1, 1]],
    
           [[1, 0],
            [1, 0]],
    
           [[1, 0],
            [0, 1]],
    
           [[1, 0],
            [0, 0]],
    
           [[0, 1],
            [1, 1]],
    
           [[0, 1],
            [1, 0]],
    
           [[0, 1],
            [0, 1]],
    
           [[0, 1],
            [0, 0]],
    
           [[0, 0],
            [1, 1]],
    
           [[0, 0],
            [1, 0]],
    
           [[0, 0],
            [0, 1]],
    
           [[0, 0],
            [0, 0]]])
    

    注意n, m = 16, 162**(16*16) 组合,大约是10**77,太大而无法放入内存。在这种情况下,您可能必须自己处理每个矩阵:

    def get_combinations(n, m):
        for flat in product([1, 0], repeat=n*m):
            yield np.reshape(flat, (n, m))
    

    你可以这样使用:

    from itertools import islice
    
    for m in islice(get_combinations(3, 3), 3):  # only get the first three
        print(m)
    
    [[1 1 1]
     [1 1 1]
     [1 1 1]]
    [[1 1 1]
     [1 1 1]
     [1 1 0]]
    [[1 1 1]
     [1 1 1]
     [1 0 1]]
    

    【讨论】:

    • @yatu:修复了像你一样使用itertools.product,但仍然使用numpy.reshape而不是多次调用numpy.arraynumpy.array_split
    • 最终选择了一个非 numpy 解决方案,不错的@Graipher +1
    猜你喜欢
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    相关资源
    最近更新 更多