我需要进行一些模拟,出于调试目的,我想使用set.seed
来获得相同的结果。以下是我想要做的例子:
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(a-b))
应该为零,但事实并非如此。我做错了什么,或者我偶然发现了一些功能?
我能够在R 2.13和R 2.14
的两个不同系统上重现这一点答案 0 :(得分:18)
我的默认答案曾经是“好然后不要那样做”(使用foreach)因为snow包为你做(可靠!)。
但正如@Spacedman指出的那样,如果你想留在doFoo
/ doRNG家庭,Renaud的新foreach就是你要找的。 p>
真正的密钥是clusterApply样式调用,用于在所有节点上设置种子。并以一种跨流协调的方式。哦,我提到过Tierney,Rossini,Li和Sevcikova snow已经为你做了差不多十年了吗?
编辑:虽然您没有询问snow,但为了完整起见,这是命令行中的一个示例:
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:~$
编辑:为了完整起见,以下是您的示例以及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>
答案 1 :(得分:7)
使用set.seed(123, kind = "L'Ecuyer-CMRG")
也可以做到这一点,并且不需要额外的包:
set.seed(123, kind = "L'Ecuyer-CMRG")
a <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)}
b <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)}
identical(a,b)
# TRUE
答案 2 :(得分:4)
doRNG包对您有用吗?我怀疑你的问题是由于两个线程都溅出了随机种子载体:
http://ftp.heanet.ie/mirrors/cran.r-project.org/web/packages/doRNG/index.html
答案 3 :(得分:2)
对于更复杂的循环,您可能必须在for循环中包含中的set.seed():
library(foreach)
library(doMC)
registerDoMC(2)
library(doRNG)
set.seed(123)
a <- foreach(i=1:2,.combine=cbind) %dopar% {
create_something <- c(1, 2, 3)
rnorm(5)
}
set.seed(123)
b <- foreach(i=1:2,.combine=cbind) %dopar% {
create_something <- c(4, 5, 6)
rnorm(5)
}
identical(a, b)
# FALSE
与
a <- foreach(i=1:2,.combine=cbind) %dopar% {
create_something <- c(1, 2, 3)
set.seed(123)
rnorm(5)
}
b <- foreach(i=1:2,.combine=cbind) %dopar% {
create_something <- c(4, 5, 6)
set.seed(123)
rnorm(5)
}
identical(a, b)
# TRUE