生成所有可能的n维k * k * ... * k-阵列,每个阵列沿轴线为1

时间:2018-01-04 12:37:33

标签: python arrays algorithm numpy

我在Python工作,需要找到一个算法来生成所有可能的n维k,k,...,k-数组,每个数组沿轴有一行。因此,该函数需要两个数字--n和k,并且应该返回一个数组列表,每个轴上包含所有可能的k行数。

例如,对于n = 2和k = 3,有6种可能性(3条水平线和3条垂直线):

[[1, 1, 1], 
 [0, 0, 0], 
 [0, 0, 0]],
[[0, 0, 0], 
 [1, 1, 1], 
 [0, 0, 0]],
[[0, 0, 0], 
 [0, 0, 0], 
 [1, 1, 1]],
[[1, 0, 0], 
 [1, 0, 0], 
 [1, 0, 0]],
[[0, 1, 0], 
 [0, 1, 0], 
 [0, 1, 0]],
[[0, 0, 1], 
 [0, 0, 1], 
 [0, 0, 1]]

对于n = 3和k = 3,有27种可能性(9条线,3条轴各3条)。

不幸的是,我甚至不知道如何为任意 n和k做这件事。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

这是一种使用itertools.product来获取放置线的索引的生成器方法。 itertools.product通常可用于替换变深度的嵌套循环:

import numpy as np
import itertools

def lines(n, k):
    for axis in range(n):
        ranges = ((slice(None),) if a==axis else range(k) for a in range(n))
        for idx in itertools.product(*ranges):
            ret = np.zeros(n*(k,), dtype=int)
            ret[idx] = 1
            yield ret

for line in lines(2, 3):
    print(line)

答案 1 :(得分:1)

如果没有numpy,你可以递归地创建矩阵,并在每个n轴上填充一个矩阵,其起始位置会因k**(n-1)种可能性而异。

k=3
n=2
indexes = [0]*n
def build_zeroes(n, k):
    if n == 2:
       return [[0]*k for _ in range(k)]
    else:
       return [build_zeroes(n-1, k) for _ in range(k)]

def compute_coordinate(position, n, k):
    coords=[]
    for i in range(n):
        coords.append(position % k)
        position = position // k
    return coords

def set_in_matrix(m, coords, value=1):
    u = m
    for c in coords[:-1]:
        u = u[c]
    u[coords[-1]] = value

for axis in range(n):
    for start_position in range(k**(n-1)):
        coords = compute_coordinate(start_position, n-1, k)
        coords.insert(axis, 0)
        m = build_zeroes(n, k)
        for i in range(k):
            coords[axis] = i
            set_in_matrix(m, coords)
        print m

这可能最终开始沉重(计算方面),因为可能会有n*k**(n-1)种可能性。