gpt4 book ai didi

r - 用 mclapply 控制种子

转载 作者:行者123 更新时间:2023-12-04 11:43:36 24 4
gpt4 key购买 nike

想象一下,我们正在执行许多过程,我想在程序开始时设置一个整体种子:例如

mylist <- list( as.list(rep(NA,3)), as.list(rep(NA,3)) )
foo <- function(x){ for(i in 1:length(x)){
x[[i]] <- sample(100,1)
}
return(x)
}

# start block
set.seed(1)
l1 <- lapply(mylist, foo)
l2 <- lapply(mylist, foo)
# end

当然在一个块中 l1l2 是不同的,但是如果我再次运行上面的块, l1 将与以前相同,而 l2 将与以前相同。

想象一下 foo 非常耗时,所以我想使用 mclapply 而不是 lapply ,所以我这样做:
library(parallel)

# start block
set.seed(1)
mclapply(mylist , foo, mc.cores = 3)
mclapply(mylist , foo, mc.cores = 3)
# end

如果我再次运行这个块,下次我会得到不同的结果。我如何产生与使用 lapply 但使用 mclappy 设置一个整体种子相同的行为。我已经浏览了 mclapply 文档,但我不确定,因为使用:
set.seed(1)
l1 <- mclapply(mylist , foo, mc.cores = 3, mc.set.seed=FALSE)
l2 <- mclapply(mylist , foo, mc.cores = 3, mc.set.seed=FALSE)

导致 l1l2 相同,这不是我想要的......

最佳答案

parallel 包特别支持与 parallel 同时引入的“L'Ecuyer-CMRG”随机数生成器。您可以使用以下方法阅读该支持的文档:

library(parallel)
?mc.reset.stream

要使用它,您首先需要启用“L'Ecuyer-CMRG”:
RNGkind("L'Ecuyer-CMRG")

完成后,代码如下:
set.seed(1)
mclapply(mylist, foo, mc.cores=3)
mclapply(mylist, foo, mc.cores=3)

将是可重现的,但对 mclapply 的两次调用将返回相同的结果。这是因为主进程中随机数生成器的状态不会通过调用 mclapply 改变。

我使用以下函数跳过 mclapply 工作人员使用的随机数流:
skip.streams <- function(n) {
x <- .Random.seed
for (i in seq_len(n))
x <- nextRNGStream(x)
assign('.Random.seed', x, pos=.GlobalEnv)
}

您可以使用此函数来获得我认为您想要的行为:
set.seed(1)
mclapply(mylist, foo, mc.cores=3)
skip.streams(3)
mclapply(mylist, foo, mc.cores=3)
skip.streams(3)

关于r - 用 mclapply 控制种子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30456481/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com