我在R中进行了一些并行模拟,我注意到种子当使用"L'Ecuyer-CMRG"rng时不会发生变化。我在读书书"平行R",以及选项mc.set.seed=TRUE应该给出每次调用mclapply((时,每个工作者都有一个新的种子。
这是我的代码:
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
编辑:同样的事情发生在我的台式机和笔记本电脑上(都是Ubuntu 12.04 LTS(。
在我看来,如果你想保证在R会话中对mclapply的后续调用得到不同的随机数,你需要用不同的值调用set.seed,删除全局变量".random.seed",或者在再次调用mclapply之前,在该R会话中至少生成一个随机数。
这种行为的原因是mclapply(例如与mcparallel不同(在内部调用mc.reset.stream。这会将存储在"并行"包中的种子重置为值"Random.seed",因此,如果再次调用mclapply时"Random.seeed"没有更改,则由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))
这里有一个删除"随机种子"的例子:
RNGkind("L'Ecuyer-CMRG")
mclapply(1:2, function(i) rnorm(2))
rm(.Random.seed)
mclapply(1:2, function(i) rnorm(2))
这里有一个在主机上生成随机数的例子:
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))
您是否考虑过使用clusterApply
而不是mclapply
?我认为使用这个框架更容易保证可复制的示例。我附上一个例子。
library(parallel)
#---- creating local cluster ----
clust <- makeCluster(detectCores())
#---- seed ----
RNGkind(kind = "L'Ecuyer-CMRG")
set.seed(1234)
s <- .Random.seed
clusterSetRNGStream(cl = clust, iseed = s)
#---- generating random numbers ----
clusterApply(cl = clust, x = 1:2, fun = function(i) rnorm(2))
#> [[1]]
#> [1] -0.0514128 0.7344781
#>
#> [[2]]
#> [1] 0.3946233 -0.6649782
clusterApply(cl = clust, x = 1:2, fun = function(i) rnorm(2))
#> [[1]]
#> [1] -1.57875323 -0.07533176
#>
#> [[2]]
#> [1] -0.3698359 -0.1564795
#---- repeating the process ----
set.seed(1234)
s <- .Random.seed
clusterSetRNGStream(cl = clust, iseed = s)
clusterApply(cl = clust, x = 1:2, fun = function(i) rnorm(2))
#> [[1]]
#> [1] -0.0514128 0.7344781
#>
#> [[2]]
#> [1] 0.3946233 -0.6649782
clusterApply(cl = clust, x = 1:2, fun = function(i) rnorm(2))
#> [[1]]
#> [1] -1.57875323 -0.07533176
#>
#> [[2]]
#> [1] -0.3698359 -0.1564795
# same result
创建于2019-03-04由reprex包(v0.2.1(
devtools::session_info()
#> Session info -------------------------------------------------------------
#> setting value
#> version R version 3.5.1 (2018-07-02)
#> system x86_64, linux-gnu
#> ui X11
#> language (EN)
#> collate en_US.UTF-8
#> tz America/Sao_Paulo
#> date 2019-03-04
#> Packages -----------------------------------------------------------------
#> package * version date source
#> backports 1.1.2 2017-12-13 CRAN (R 3.5.0)
#> base * 3.5.1 2018-07-03 local
#> compiler 3.5.1 2018-07-03 local
#> datasets * 3.5.1 2018-07-03 local
#> devtools 1.13.6 2018-06-27 CRAN (R 3.5.0)
#> digest 0.6.17 2018-09-12 cran (@0.6.17)
#> evaluate 0.11 2018-07-17 cran (@0.11)
#> graphics * 3.5.1 2018-07-03 local
#> grDevices * 3.5.1 2018-07-03 local
#> htmltools 0.3.6 2017-04-28 CRAN (R 3.5.0)
#> knitr 1.20 2018-02-20 CRAN (R 3.5.0)
#> magrittr 1.5 2014-11-22 cran (@1.5)
#> memoise 1.1.0 2017-04-21 CRAN (R 3.5.0)
#> methods * 3.5.1 2018-07-03 local
#> parallel * 3.5.1 2018-07-03 local
#> Rcpp 0.12.18 2018-07-23 cran (@0.12.18)
#> rmarkdown 1.10 2018-06-11 CRAN (R 3.5.1)
#> rprojroot 1.3-2 2018-01-03 CRAN (R 3.5.0)
#> stats * 3.5.1 2018-07-03 local
#> stringi 1.2.4 2018-07-20 cran (@1.2.4)
#> stringr 1.3.1 2018-05-10 CRAN (R 3.5.0)
#> tools 3.5.1 2018-07-03 local
#> utils * 3.5.1 2018-07-03 local
#> withr 2.1.2 2018-03-15 CRAN (R 3.5.0)
#> yaml 2.2.0 2018-07-25 cran (@2.2.0)