Эти ответы работают, но все они требуют вызова недетерминированной функции, такой как sample()
в цикле.Это не инвариантный к циклу код (каждый раз он случайный), но он все равно может быть удален из цикла for
.Хитрость заключается в том, чтобы использовать аргумент n
и сгенерировать все случайные числа, которые вам нужны заранее (если ваша проблема это позволяет, некоторые могут нет, но многие это делают).Теперь вы делаете один звонок, а не n
, что имеет значение, если ваш n
большой.Вот быстрый пример случайного блуждания (но многие проблемы могут быть сформулированы таким образом).Кроме того, полное раскрытие: у меня не было любого кофе сегодня, поэтому, пожалуйста, укажите, если вы видите ошибку: -)
steps <- 30
n <- 100
directions <- c(-1, 1)
results <- vector('list', n)
for (i in seq_len(n)) {
walk <- numeric(steps)
for (s in seq_len(steps)) {
walk[s] <- sample(directions, 1)
}
results[[i]] <- sum(walk)
}
Мы можем переписать это одним вызовом sample()
:
all.steps <- sample(directions, n*steps, replace=TRUE)
dim(all.steps) <- c(n, steps)
walks <- apply(all.steps, 1, sum)
Подтверждение увеличения скорости (n = 10000):
> system.time({
+ for (i in seq_len(n)) {
+ walk <- numeric(steps)
+ for (s in seq_len(steps)) {
+ walk[s] <- sample(directions, 1)
+ }
+ results[[i]] <- sum(walk)
+ }})
user system elapsed
4.231 0.332 4.758
> system.time({
+ all.steps <- sample(directions, n*steps, replace=TRUE)
+ dim(all.steps) <- c(n, steps)
+ walks <- apply(all.steps, 1, sum)
+ })
user system elapsed
0.010 0.001 0.012
Если для моделирования требуется только одна случайная величина на вызов функции моделирования, используйте sapply()
илиеще лучше multicore
пакет mclapply()
.Пакет Revolution Analytics foreach
может также использоваться здесь.Кроме того, у JD Long есть отличная презентация и пост о симуляции вещей в R на Hadoop через EMR Amazon здесь (я не могу найти видео, но я уверен, что кто-то узнает).
Возьмите начальные очки:
- Предварительно выделите с помощью
numeric(n)
или vector('list', n)
- Выдвиньте инвариантный код из
for
циклов.Умело выталкивайте стохастические функции из кода с их аргументом n
. - Старайтесь для
sapply()
или lapply()
, или еще лучше mclapply
. - Не используйте
x <- c(x, rnorm(100))
.Каждый раз, когда вы делаете это, член R-core убивает щенка.