使用“L'Ecuyer-CMRG”RNG 时,R 不会重置种子?

Mat*_*olo 8 parallel-processing r prng

我在 R 中进行了一些并行模拟,我注意到使用“L'Ecuyer-CMRG”rng 时种子没有改变。我正在阅读“Parallel R”一书,每次调用 mclapply() 时,选项 mc.set.seed = TRUE 应该给每个工人一个新种子。

这是我的代码:

library(parallel)
RNGkind("L'Ecuyer-CMRG")

mclapply(1:2, function(n) rnorm(n), mc.set.seed = TRUE)
[[1]]
[1] -0.7125037

[[2]]
[1] -0.9013552  0.3445190

mclapply(1:2, function(n) rnorm(n), mc.set.seed = TRUE)
[[1]]
[1] -0.7125037

[[2]]
[1] -0.9013552  0.3445190
Run Code Online (Sandbox Code Playgroud)

编辑:同样的事情发生在我的台式机和我的笔记本电脑上(都是 Ubuntu 12.04 LTS)。

Ste*_*ton 5

在我看来,如果您想保证在 R 会话中对 mclapply 的后续调用获得不同的随机数,则需要使用不同的值调用 set.seed,删除全局变量“.Random.seed”,或者生成在再次调用 mclapply 之前,该 R 会话中至少有一个随机数。

这种行为的原因是 mclapply(例如不同于 mcparallel)在内部调用 mc.reset.stream。这会将隐藏在“parallel”包中的种子重置为“.Random.seed”的值,因此如果再次调用 mclapply 时“.Random.seed”没有改变,则由 mclapply 启动的工作人员将获得与以前相同的随机数。

请注意,对于 clusterApply 和 parLapply 等函数,情况并非如此,因为它们使用持久性工作程序,因此会继续从其 RNG 流中抽取随机数。但是每次调用 mclapply 时都会分叉新的工人,这大概会使这种行为变得更加困难。

下面是使用 mclapply 将种子设置为不同值以获取不同随机数的示例:

RNGkind("L'Ecuyer-CMRG")
set.seed(100)
mclapply(1:2, function(i) rnorm(2))
set.seed(101)
mclapply(1:2, function(i) rnorm(2))
Run Code Online (Sandbox Code Playgroud)

这是删除“.Random.seed”的示例:

RNGkind("L'Ecuyer-CMRG")
mclapply(1:2, function(i) rnorm(2))
rm(.Random.seed)
mclapply(1:2, function(i) rnorm(2))
Run Code Online (Sandbox Code Playgroud)

这是在 master 上生成随机数的示例:

RNGkind("L'Ecuyer-CMRG")
mclapply(1:2, function(i) rnorm(2))
rnorm(1)
mclapply(1:2, function(i) rnorm(2))
Run Code Online (Sandbox Code Playgroud)

我不确定哪种方法是最好的,但这可能取决于您要尝试做什么。

虽然看起来只是多次调用 mclapply 而不更改“.Random.seed”会导致可重复的结果,但我不知道这是否有保证。为了保证可重复的结果,我认为您需要调用 set.seed:

RNGkind("L'Ecuyer-CMRG")
set.seed(1234)
mclapply(1:2, function(i) rnorm(2))
set.seed(1234)
mclapply(1:2, function(i) rnorm(2))
Run Code Online (Sandbox Code Playgroud)