我正在尝试使用 R 学习异步编程,以便我可以实现一个需要生成具有指定种子的随机数(始终具有指定种子)的应用程序。我一直在使用R.utils::withSeed
它,但我知道它withr::with_seed
也存在,所以我想我可以检查一下。
我知道随机数生成很棘手,所以我一直在尝试运行简单的示例来尝试了解事情是如何工作的。我需要:
- ...使用相同的种子时总是得到相同的随机数
- ...无论我是否使用异步框架,都可以使用相同的种子获得相同的随机数(因此我应该能够在 Promise 之外运行代码并获得相同的答案)
在下面的代码中,我定义了两个函数来生成随机数,使用withr::with_seed
或设置种子R.utils::withSeed
。
- 当在 promise 之外运行时,这两个函数给了我相同的答案。
- 这两个函数在 Promise 中运行时给出不同的答案。
- 该
withr::with_seed
版本在承诺内部或外部给出了相同的答案。 - 该
R.utils::withSeed
版本在承诺内部或外部给出了不同的答案。
然而,答案似乎在多次运行中是一致的。
我的问题是:为什么?这是一个错误R.utils::withSeed
,还是我误解了什么?
代码
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)