R中蒙特卡洛模拟批量随机数的可复现性与序列延续问题
R蒙特卡洛模拟分批次执行的随机序列延续与可复现性问题
我在R中运行蒙特卡洛模拟,受内存和时间限制需要分批次执行,且要求结果可复现。原本计划每批结束时保存RNG(随机数生成器)状态,下一批加载该状态以延续伪随机序列,但遇到问题:当一批内生成多种类型随机数(unif、norm、lognorm等)时,可复现性失效。
以下是示例代码说明问题场景:
# 查看会话初始RNG状态 state_0 <- .Random.seed # 设置种子后状态改变 set.seed(42) state_1 <- .Random.seed all.equal(state_1,state_2) # 原代码state_2未定义,保留原文内容 # 生成随机数 unif_1 <- runif(10) state_2 <- .Random.seed # 随机状态已改变 all.equal(state_1,state_2) #[1] "Mean relative difference: 1.273813" # 继续生成新的随机数,延续序列 unif_2 <- runif(10) all.equal(unif_1,unif_2) #[1] "Mean relative difference: 0.4847836" # 重置随机状态,重新生成相同序列 .Random.seed <- state_1 unif_1_2 <- runif(20) all.equal(unif_1_2, c(unif_1,unif_2)) #[1] TRUE # 期望分批次生成随机数,同时延续序列并保证可复现 generate_rn <- function(num, rng_state){ .Random.seed <- rng_state unif <- runif(num) norm <- rnorm(num) random_numbers <- cbind(unif,norm) rng_state <- .Random.seed return(list(random_numbers,rng_state)) } # 用初始状态生成第一批随机数 batch_1 <- generate_rn(10,state_1) # 用第一批结束后的状态生成第二批随机数 batch_2 <- generate_rn(10,batch_1[[2]]) # 一次性生成20组(含unif和norm)的结果 batch_1_2 <- generate_rn(20,state_1) # 两种方式生成的总随机数数量相同,最终RNG状态一致 all.equal(batch_1_2[[2]],batch_2[[2]]) # [1] TRUE # 但生成的随机数结果不一致 all.equal(batch_1_2[[1]],rbind(batch_1[[1]],batch_2[[1]])) # [1] "Mean relative difference: 1.639137" # 且第一批的前10个均匀分布随机数,和之前单独生成的unif_1也不一致 all.equal(unif_1,batch_1[[1]][,1]) # [1] "Mean relative difference: 0.5737766"
补充疑问(针对jblood94回答的回复)
感谢您的回复,这解决了可复现性问题且实现更简洁。但我仍想知道是否有办法在批次间延续随机序列?例如调整函数仅生成单一类型随机数,调用两次生成5+5个随机数,与一次生成10个的结果后半段不匹配,因为前者用了不同种子而非延续序列。
示例代码:
generate_single_rn<- function(num, seed){ set.seed(seed) (runif(num)) } nums_3 <- c(5,5) nums_4 <- c(10) seeds_3 <- seeds[1:2] # 假设seeds是预先保存的种子序列 seeds_4 <- seeds[1] res_3 <- Map(generate_single_rn, nums_3,seeds_3) #> res_3 #[[1]] #[1] 0.82047671 0.62451587 0.83677751 0.06815233 0.97957789 #[[2]] #[1] 0.6394495 0.6867910 0.6124927 0.7527410 0.6202278 res_4 <- Map(generate_single_rn, nums_4,seeds_4) #> res_4 #[[1]] #[1] 0.82047671 0.62451587 0.83677751 0.06815233 0.97957789 0.07133851 0.84175755 0.79822464 #[9] 0.84784338 0.41118260
考虑到MT RNG周期极长,即使生成大量随机数,序列重叠概率极低,这或许不是问题。再次感谢。
内容的提问来源于stack exchange,提问作者DataNoob
相关产品推荐
相关产品推荐

