Сгенерировать все перестановки из n записей в матрице w x h.

#python-3.x #multidimensional-array #combinations #itertools

#python-3.x #многомерный массив #комбинации #itertools

Вопрос:

Я хотел бы сгенерировать все перестановки из n записей в матрице w x h: пример с матрицей 2×2 и n = 1:

 | 1 0 |
| 0 0 |

| 0 1 |
| 0 0 |

| 0 0 |
| 1 0 |

| 0 0 |
| 0 1 |
 

пример с матрицей 3×3 и n = 2 (частично):

 | 0 0 1|
| 0 0 1|
| 0 0 0|

| 1 0 0|
| 0 0 1|
| 0 0 0|
 

Я хотел бы избежать использования numpy, поэтому я думаю, что itertool — это правильный путь. Я смотрю на одномерные решения, но все, что я получил, это что-то немного другое, например, itertools.product, который повторяется с фиксированным числом значений, например

 itertools.product([0,'n'],repeat=6)

[(0, 0, 0, 0, 0, 0),....('n', 'n', 'n', 'n', 'n', 'n')]
 

любой намек будет с радостью оценен

Ответ №1:

Есть w * h доступные позиции, в которые вы хотите поместить n 1, а остальные заполнить 0.

Вы можете создать все возможные комбинации позиций для n единиц, используя itertools.combinations :

 >>> w = 2
>>> h = 2
>>> n = 2
>>> list(itertools.combinations(range(w * h), n))
[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
 

Чтобы создать фактическую матрицу (в виде списка единиц и 0) из одного из кортежей позиций, вы можете, например, использовать понимание списка:

 >>> positions = (1, 3)
>>> [1 if i in positions else 0 for i in range(w * h)]
[0, 1, 0, 1]
 

Для очень больших n поиск i in positions становится неэффективным, и было бы лучше изменить это на функцию типа:

 def create_matrix(positions):
    matrix = [0] * w * h
    for i in positions:
        matrix[i] = 1
    return matrix
 

Теперь вы можете собрать все вместе:

 >>> [[1 if i in p else 0 for i in range(w * h)]
...  for p in itertools.permutations(range(w * h), n)]
[[1, 1, 0, 0], [1, 0, 1, 0], [1, 0, 0, 1], [1, 1, 0, 0], [0, 1, 1, 0], [0, 1, 0, 1],
 [1, 0, 1, 0], [0, 1, 1, 0], [0, 0, 1, 1], [1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1]]
 

Или, если вы используете create_matrix функцию:

 >>> [create_matrix(p) for p in itertools.permutations(range(w * h), n)]