Поскольку вам нужно 5 случайных чисел для суммирования с 1, у вас действительно есть только 4 независимых числа и одно зависимое число.
mymins <- c(0.3, 0.1, 0, 0.2, 0.05)
mymaxs <- c(0.9, 1, 1, 1, 0.7)
set.seed(42)
iter <- 1000
while(iter > 0 &&
(
(1 - sum(x <- runif(4, mymins[-5], mymaxs[-5]))) < mymins[5] ||
(1 - sum(x)) > mymaxs[5]
)
) iter <- iter - 1
if (iter < 1) {
# failed
stop("unable to find something within 1000 iterations")
} else {
x <- c(x, 1-sum(x))
}
sum(x)
# [1] 1
all(mymins <= x & x <= mymaxs)
# [1] TRUE
x
# [1] 0.37732330 0.21618036 0.07225311 0.24250359 0.09173965
Причина, по которой я использую iter
, заключается в том, чтобы убедиться, что вы не тратить "бесконечное" количество времени, чтобы найти что-то. Если ваша комбинация mymins
и mymaxs
делает это математически неосуществимым (как в первом примере), то вам не нужно вращаться вечно. Если математически маловероятно найти его за разумное время, вам нужно взвесить, сколько времени вы хотите сделать это.
Одна из причин, по которой это занимает так много времени, заключается в том, что мы многократно увеличиваем энтропию. Если вы ожидаете, что это значение будет go в течение длительного времени, тогда, как правило, лучше предварительно рассчитать столько, сколько вы считаете нужным (в целом), и запустить все как матрицу.
set.seed(42)
n <- 10000
m <- matrix(runif(prod(n, length(mymins)-1)), nrow = n)
m <- t(t(m) * (mymaxs[-5] - mymins[-5]) + mymins[-5])
remainders <- (1 - rowSums(m))
ind <- mymins[5] <= remainders & remainders <= mymaxs[5]
table(ind)
# ind
# FALSE TRUE
# 9981 19
m <- cbind(m[ind,,drop=FALSE], remainders[ind])
nrow(m)
# [1] 19
rowSums(m)
# [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
head(m)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0.3405821 0.1306152 0.05931363 0.2199362 0.24955282
# [2,] 0.3601376 0.1367465 0.20235704 0.2477507 0.05300821
# [3,] 0.4469526 0.1279795 0.02265618 0.2881733 0.11423845
# [4,] 0.5450527 0.1029903 0.07503371 0.2052423 0.07168103
# [5,] 0.3161519 0.1469783 0.15290720 0.3268470 0.05711557
# [6,] 0.4782448 0.1185735 0.01664063 0.2178225 0.16871845
all(
mymins[1] <= m[,1] & m[,1] <= mymaxs[1],
mymins[2] <= m[,2] & m[,2] <= mymaxs[2],
mymins[3] <= m[,3] & m[,3] <= mymaxs[3],
mymins[4] <= m[,4] & m[,4] <= mymaxs[4],
mymins[5] <= m[,5] & m[,5] <= mymaxs[5]
)
# [1] TRUE
На этот раз потребовалось 10000 попыток собрать 19 правильных комбинаций. Это может занять больше или меньше попыток, основанных на случайности, так что, ymmv, в отношении того, сколько вам нужно предварительно сгенерировать.