在我看来,如果您想保证在 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))
这是删除“.Random.seed”的示例:
RNGkind("L'Ecuyer-CMRG")
mclapply(1:2, function(i) rnorm(2))
rm(.Random.seed)
mclapply(1:2, function(i) rnorm(2))
下面是在 master 上生成随机数的示例:
RNGkind("L'Ecuyer-CMRG")
mclapply(1:2, function(i) rnorm(2))
rnorm(1)
mclapply(1:2, function(i) rnorm(2))
我不确定哪个是最好的方法,但这可能取决于你想要做什么。
尽管看起来简单地多次调用 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))