简体   繁体   English

生成所有可能的n维k * k *…* k数组,每个数组沿轴均带有一线

[英]Generate all possible n-dimensional k*k*…*k-arrays each with line of ones along axis

I'm working in Python and need to find an algorithm to generate all possible n-dimensional k,k,...,k-arrays each with a line of ones along an axis. 我在Python中工作,需要找到一种算法来生成所有可能的n维k,k,...,k数组,每个数组沿轴都带有一行。 So, the function takes two numbers - n and k and should return a list of arrays with all possible lines of k ones along each axis. 因此,该函数采用两个数字-n和k,并且应返回一个数组列表,该数组包含沿每个轴的所有可能的k行。

For example for n = 2 and k = 3 there are 6 possibilities (with 3 horizontal lines and 3 vertical): 例如,对于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]]

For n = 3 and k = 3 there are 27 possibilities (9 lines with 3 ones each along each of 3 axes). 对于n = 3和k = 3,存在27种可能性(9条线,沿着3条轴分别有3条)。

Unfortunately, I don't have even an idea of how to do it for arbitrary n and k. 不幸的是,我什至不知道如何对任意 n和k进行操作。 Any suggestions? 有什么建议么?

Here is a generator approach using itertools.product to get the indices for placing the line. 这是一种使用itertools.product的生成器方法来获取放置线的索引。 itertools.product is often useful to replace nested loops of variable depth: 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)

Without numpy, you can create the matrix recursively, and fill the ones along each of the n axis with a starting position that will vary in the k**(n-1) possibilities. 如果不使用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

This might endup begin heavy (computations-wise), because there wil be n*k**(n-1) possibilities. 由于可能存在n*k**(n-1)可能性,因此最终可能开始比较繁琐(在计算方面)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM