То, что вы описываете, достижимо с помощью (мощной) библиотеки Python itertools
, а затем отфильтровывает ее в зависимости от вашего состояния.Но то, что вы хотите, это скорее product , а не комбинация массива.
Вот один из способов сделать это, предполагая аргументы N и M.
import numpy as np
import itertools
p = np.arange(N)
Получите произведения длины 3:
product_iterator = itertools.product(p, repeat=M)
Это дает вам объект-итератор.Вы можете получить конкретный список из него (и немедленно превратить его в массив, в этом примере, хотя я назвал его списком):
product_list = np.array(list(product_iterator))
В этот момент вы получили массив всех 27 комбинаций:[[0 0 0], [0 0 1], [0 0 2], ..., [2 2 1], [2 2 2]].Теперь вы можете отфильтровать их по желаемым критериям.
В вашем случае, «отсутствие повторяющихся элементов подряд» означает проверку того, что разность между двумя последовательными элементами никогда не равна нулю.Таким образом, мы получаем различия:
diffs = np.diff(product_list,axis=1)
Это дает:
[[ 0 0]
[ 0 1]
[ 0 2]
[ 1 -1]
[ 1 0]
[ 1 1]
[ 2 -2]
[ 2 -1]
[ 2 0]
[-1 0]
[-1 1]
[-1 2]
[ 0 -1]
[ 0 0]
[ 0 1]
[ 1 -2]
[ 1 -1]
[ 1 0]
[-2 0]
[-2 1]
[-2 2]
[-1 -1]
[-1 0]
[-1 1]
[ 0 -2]
[ 0 -1]
[ 0 0]]
И теперь мы проверяем, строка за строкой, есть ли нули:
no_consec_indexes = np.apply_along_axis(lambda x: np.all(x), 1, diffs)
Это дает массив логических значений no_consec_indexes
:
array([False, False, False, True, False, True, True, True, False,
False, True, True, False, False, False, True, True, False,
False, True, True, True, False, True, False, False, False])
Вы можете использовать его для фильтрации исходного массива продуктов:
product_list[no_consec_indexes]
Что дает желаемый ответ:
array([[0, 1, 0],
[0, 1, 2],
[0, 2, 0],
[0, 2, 1],
[1, 0, 1],
[1, 0, 2],
[1, 2, 0],
[1, 2, 1],
[2, 0, 1],
[2, 0, 2],
[2, 1, 0],
[2, 1, 2]])