Почему withr :: with_seed и R.utils :: withSeed генерируют разные результаты при использовании в асинхронном коде?
Я пытаюсь изучить асинхронное программирование с использованием R, чтобы я мог реализовать приложение, которое требует генерации случайных чисел с указанными начальными числами ( всегда с указанными начальными числами ). Я использовал для этого, но знаю, что он тоже существует, поэтому подумал, что могу это проверить.
Я знаю, что генерация случайных чисел - сложная задача, поэтому я пытался запустить простые примеры, чтобы попытаться понять, как все работает. Мне нужно:
- ... чтобы всегда получать одни и те же случайные числа при использовании одного и того же семени
- ... чтобы получить одни и те же случайные числа с одним и тем же семенем, независимо от того, использую ли я асинхронный фреймворк (чтобы я мог запустить код вне обещания и получить тот же ответ)
В приведенном ниже коде я определяю две функции для генерации случайных чисел, устанавливая начальное число с помощью или.
- Эти две функции дают мне одинаковый ответ, когда выполняются вне обещания.
- Эти две функции дают разные ответы при запуске внутри обещания.
- В
версия дает один и тот же ответ внутри или вне обещания. - Версия дает разные ответы внутри или вне обещания.
Однако ответы кажутся одинаковыми для нескольких прогонов.
У меня вопрос: почему? Это ошибка в
Код
library(future)
library(promises)
plan(multisession)
s0_R = function(seed = 1, n = 1){
R.utils::withSeed(expr = {
rnorm(n)
}, seed = seed)
}
s0_w = function(seed = 1, n = 1){
withr::with_seed(
seed = seed,
code = {
rnorm(n)
})
}
s_R = function(seed = 1, n = 1){
future_promise(
{
Sys.sleep(5)
s0_R(seed, n)
},
seed = TRUE
)
}
s_w = function(seed = 1, n = 1){
future_promise(
{
Sys.sleep(5)
s0_w(seed, n)
},
seed = TRUE
)
}
s0_R(123) %>%
paste(" (R.utils::withSeed)\n") %>%
cat()
# -0.560475646552213 (R.utils::withSeed)
s0_w(123) %>%
paste(" (withr::with_seed)\n") %>%
cat()
# -0.560475646552213 (withr::with_seed)
s_R(123) %...>%
paste(" (async, R.utils::withSeed)\n") %...>%
cat()
s_w(123) %...>%
paste(" (async, withr::with_seed)\n") %...>%
cat()
# Results occur later...
# -0.968592726552943 (async, R.utils::withSeed)
# -0.560475646552213 (async, withr::with_seed)
1 ответ
В
future
package устанавливает тип RNG по умолчанию на L'Ecuyer-CMRG, тогда как R по умолчанию использует Mersenne-Twister.
withr::with_seed
сбрасывает тип ГСЧ на
"default"
(например, Mersenne-Twister), если это явно не указано в
.rng_kind
аргумент.
R.utils::withSeed
, с другой стороны, по умолчанию ничего не делает с типом ГСЧ, но тип ГСЧ можно указать с помощью
...
список аргументов, переданный в
set.seed
. В вашем примере
s0_R
можно изменить следующим образом, чтобы получить одинаковые результаты внутри и за пределами обещания.
s0_R = function(seed = 1, n = 1){
R.utils::withSeed(expr = {
rnorm(n)
}, seed = seed, kind = "default")
}