doRNG 和顺序随机数因相同的种子而不同 - R (foreach, doParallel, doRNG)

doRNG and sequential random numbers differ with same seed - R (foreach, doParallel, doRNG)

我正在做一个模拟,它对样本数量重复一些独立的计算。我想让它平行以加快速度。在每个示例中,我生成一些随机数(使用 rnorm)。我读到(并看到)doParallel 数是不可重复的,所以我想使用 doRNG(实际上它会根据核心数量独立生成相同的随机数。但是令我惊讶的是,doRNG 生成的数字与顺序 for 循环不同,甚至当我没有注册并行后端时,计算是按顺序完成的(当使用 %dorng% 运算符时,我得到与注册并行后端相同的结果),但是我使用 %dopar% 得到相同的数字,但没有注册并行后端。为什么是那?我能以某种方式参数化 foreach/doRNG 以获得与顺序 for 循环中相同的随机数吗? 我想用它来检查我没有搞砸任何事情同时移动到平行。

下面是一个简化的例子(注意我没有注册并行后端):

library(foreach)
library(doRNG)
library(doParallel)
RNGkind("L'Ecuyer-CMRG")

set.seed(123)
rn3 <- foreach(i=1:20, .combine = 'c') %dopar%{ 
  return(rnorm(1,0,1))
}


rn1 <- foreach(i=1:20, .combine = 'c', .options.RNG=123) %dorng%{ 
  return(rnorm(1,0,1))
}

set.seed(123)
rn2 <- foreach(i=1:20, .combine = 'c') %dorng%{ 
  return(rnorm(1,0,1))
}


rn4 <- rep(0,20)
set.seed(123)
for(i in 1:20){
  rn4[i] <- (rnorm(1,0,1))
}

identical(rn1, rn2) 
identical(rn1, rn3)
identical(rn1, rn4)
identical(rn3, rn4)

表明rn1和rn2(在dorng中设置种子的两种不同方法)以及rn3和rn4(doParallel和for循环)是相同的,但是rn1/rn2和rn3/rn4确实彼此不匹配。

编辑:我意识到使用了不同的伪随机数生成器。在 %dorng% 中,我们使用 L'Ecuyer-CMRG,而在 base R 中,默认是 Mersenne-Twister。但是,当我设置它时,L'Ecuyer-CMRG 也只匹配第一个数字。我调整了代码以添加设置不同的 PRNG

好的,终于找到原因了(刚才的评论有帮助)。 %dorng% 所做的是为 foreach 中的每个值 i 生成随机种子。由于要使用 for 循环获得与 %dorng% 中相同的数字,我们需要首先使用 L'Ecuyer-CMRG PRNG 并且我们需要设置相同数量的种子。在那种情况下,将在 for-loop 中复制的代码是:

RNGkind("L'Ecuyer-CMRG")

rn6 <- rep(0,20)
for(i in 1:20){
  .Random.seed <- attr(rn1,"rng")[[i]] #using seeds from rn1 from question
  rn6[i] <- (rnorm(1,0,1))
}