Можно ли ограничить результат skopt.Lhs.generate?

Скажем, у меня есть такой массив:

      from skopt.space import Space
from skopt.sampler import Lhs
import numpy as np

np.random.seed(42)

rows = 5
cols = 3

dummy = np.zeros((rows, cols))

array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])

и теперь я хотел бы использовать skopt.Lhs.generate для заполнения определенных позиций этого массива 1 при этом я хотел бы исключить определенные позиции, хранящиеся в:

      ignore = np.array([
    [3, 1],
    [4, 1]
])

Как бы я сделал это лучше всего?

я могу сделать

      space = Space([(0, rows - 1), (0, cols - 1)])

lhs = Lhs(criterion="maximin", iterations=1000)
lh = np.array(lhs.generate(space.dimensions, 3))

dummy[lh[:, 0], lh[:, 1]] = 1

который дает

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

но как видно положение 4, 1 занят, но не должен.

Один из способов - поставить lhs.generate позвонить в while цикл, а затем всегда проверяет, находится ли какой-либо элемент в ignore но мне интересно, есть ли более простое решение этой проблемы.

1 ответ

Для полноты картины решение, использующее while цикл может выглядеть так:

      from skopt.space import Space
from skopt.sampler import Lhs
import numpy as np

def contains_element(a, b):
    return any(li in a for li in b)

np.random.seed(42)

rows = 5
cols = 3

dummy = np.zeros((rows, cols))

ignore = [
    [3, 1],
    [4, 1]
]

space = Space([(0, rows - 1), (0, cols - 1)])

contains_row = True
while contains_row:

    lhs = Lhs(criterion="maximin", iterations=1000)
    lh = lhs.generate(space.dimensions, 3)
    contains_row = contains_element(lh, ignore)
    print(lh)
    print(contains_row)
    print('-----------------------\n')

lh = np.array(lh)
dummy[lh[:, 0], lh[:, 1]] = 1

print(dummy)

который печатает

      [[2, 0], [0, 2], [4, 1]]
True
-----------------------

[[2, 0], [1, 2], [4, 1]]
True
-----------------------

[[4, 2], [0, 1], [2, 0]]
False
-----------------------

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

Итак, здесь требуется 3 итерации, пока не будут найдены позиции, которых нет в ignore. Если кто-нибудь знает более простое решение, дайте мне знать!

Другие вопросы по тегам