Я хочу получить выборку целых чисел в R, но также установить ограничения, например, «3 всегда предшествует 2» и «8 всегда предшествует 5».
Обновлено: целые числа не обязательно должны быть рядом друг с другом, например, c(x,3,y,2,z) и c(8,x,y,z,5) являются приемлемыми, учитывая эти ограничения.
Без каких-либо ограничений можно было бы просто написать:
sample(1:10)
...и всё, но теперь нам нужно нечто большее. Мне нравится думать с помощью таблиц или матриц, поэтому описание отношений с матрицей было моим решением этой проблемы, т.е.
# Create constraint matrix
constraint_matrix <- matrix(0, nrow = 10, ncol = 10)
# Set constraints
constraint_matrix[3, 2] <- 1 # 3 comes before 2
constraint_matrix[8, 5] <- 1 # 8 comes before 5
# Check, if generated output satisfies set constraints
check_constraints <- function(numbers, constraint_matrix) {
for (i in 1:(length(numbers) - 1)) {
if (constraint_matrix[numbers[i+1], numbers[i]] == 1) {
return(FALSE) # A constraint NOT satisfied
}
}
return(TRUE) # All constraints are satisfied
}
# Generate random order and check if constraints are satisfies
set.seed(123)
numbers <- sample(1:10)
while (!check_constraints(numbers, contstraint_matrix)) {
numbers <- sample(1:10)
}
print(numbers)
Мой вопрос: есть ли лучшая оптимизированная функция для этого? Или кто-то знает лучший алгоритм для этой задачи?
Вы всегда отбираете образцы без замены?
Эта проблема представляет собой случайную топологическую разновидность DAG. Несколько ссылок могут оказаться полезными: ссылка1 , ссылка2 , ссылка3 , ссылка4.
@FelixJassler Целые числа не обязательно должны быть рядом друг с другом, я уточню это.
@CarlWitthoft Я всегда беру образцы без замены.
Проверьте, соответствует ли порядок ограничениям, если нет, просто поменяйте их местами:
set.seed(1); x <- sample(1:10)
x
# [1] 9 4 7 1 2 5 3 10 6 8
#"3 comes always before 2" and "8 comes always before 5".
cons <- list(c(3, 2), c(8, 5))
for(i in seq_along(cons)){
ix <- match(cons[[ i ]], x)
if (ix[ 1 ] > ix[ 2 ]) x[ rev(ix) ] <- cons[[ i ]]
}
x
# [1] 9 4 7 1 3 8 2 10 6 5
Ваш запрос неясен. Вот простой способ 2
и 5
следовать любым желаемым значениям.
samp <- 1:10
lastones <- c(2,5)
foo <- sample(samp[-lastones])
foo <- c(foo, lastones)
Должен ли сразу за
3
следовать2
, как вc(3, 2, ...)
или вc(..., 3, 2, ...)
? Или что-то вродеc(3, ..., 2, ...)
тоже разрешено?