问题描述
我需要进行一些模拟,出于调试目的,我想使用 set.seed
来获得相同的结果.这是我正在尝试做的示例:
I need to do some simulations and for debugging purposes I want to use set.seed
to get the same result. Here is the example of what I am trying to do:
library(foreach)
library(doMC)
registerDoMC(2)
set.seed(123)
a <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)}
set.seed(123)
b <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)}
对象 a
和 b
应该相同,即 sum(abs(ab))
应该为零,但事实并非如此.我做错了什么,还是我偶然发现了某些功能?
Objects a
and b
should be identical, i.e. sum(abs(a-b))
should be zero, but this is not the case. I am doing something wrong, or have I stumbled on to some feature?
我可以使用 R 2.13 和 R 2.14 在两个不同的系统上重现这个
I am able to reproduce this on two different systems with R 2.13 and R 2.14
推荐答案
我的默认答案曾经是那么不要那样做"(使用 foreach) 作为 snow 包为你做这件事(可靠!).
My default answer used to be "well then don't do that" (using foreach) as the snow package does this (reliably!) for you.
但正如@Spacedman 指出的那样,如果您想留下来,Renaud 的新 doRNG 正是您要寻找的与 doFoo
/foreach 家族一起.
But as @Spacedman points out, Renaud's new doRNG is what you are looking for if you want to remain with the doFoo
/ foreach family.
不过,真正的关键是一个 clusterApply 风格的调用,用于在所有节点上设置种子.并以跨流协调的方式.哦,我有没有提到 Tierney、Rossini、Li 和 Sevcikova 的 snow 几乎已经为你做这件事了十年?
The real key though is a clusterApply-style call to get the seeds set on all nodes. And in a fashion that coordinated across streams. Oh, and did I mention that snow by Tierney, Rossini, Li and Sevcikova has been doing this for you for almost a decade?
虽然您没有询问 snow,但为了完整性这是命令行中的示例:
And while you didn't ask about snow, for completeness here is an example from the command-line:
edd@max:~$ r -lsnow -e'cl <- makeSOCKcluster(c("localhost","localhost"));
clusterSetupRNG(cl);
print(do.call("rbind", clusterApply(cl, 1:4,
function(x) { stats::rnorm(1) } )))'
Loading required package: utils
Loading required package: utils
Loading required package: rlecuyer
[,1]
[1,] -1.1406340
[2,] 0.7049582
[3,] -0.4981589
[4,] 0.4821092
edd@max:~$ r -lsnow -e'cl <- makeSOCKcluster(c("localhost","localhost"));
clusterSetupRNG(cl);
print(do.call("rbind", clusterApply(cl, 1:4,
function(x) { stats::rnorm(1) } )))'
Loading required package: utils
Loading required package: utils
Loading required package: rlecuyer
[,1]
[1,] -1.1406340
[2,] 0.7049582
[3,] -0.4981589
[4,] 0.4821092
edd@max:~$
为了完整起见,这里是您的示例与 文档中的内容相结合做
And for completeness, here is your example combined with what is in the docs for doRNG
> library(foreach)
R> library(doMC)
Loading required package: multicore
Attaching package: ‘multicore’
The following object(s) are masked from ‘package:parallel’:
mclapply, mcparallel, pvec
R> registerDoMC(2)
R> library(doRNG)
R> set.seed(123)
R> a <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)}
R> set.seed(123)
R> b <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)}
R> identical(a,b)
[1] FALSE ## ie standard approach not reproducible
R>
R> seed <- doRNGseed()
R> a <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) }
R> b <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) }
R> doRNGseed(seed)
R> a1 <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) }
R> b1 <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) }
R> identical(a,a1) && identical(b,b1)
[1] TRUE ## all is well now with doRNGseed()
R>
这篇关于如何使用 foreach 和 doMC 包为随机模拟设置种子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!