我正在开发一个大学项目,该项目模拟 6/49 乐透运气游戏。 通过选择 1 到 49 之间的 6 个不同的数字来创建票证。 我要模拟10^6张彩票并将其与幸运彩票进行比较。 我想找出随机彩票的 6 个数字与幸运彩票的 6 个数字的交集的基数。但如果我对 10^6 张彩票做一次,得到一张与幸运彩票完美匹配的彩票的概率就很低了。所以我尝试执行此过程“nr_esantion”次(即 20 次)并计算平均值。
这是我的方法:
nr_esantion<-30
es<-10^6
nr_49<-1:49
table_1 <- rep(0,7)
table_1
for(i in 1:nr_esantion)
{
lucky <- sample(nr_49,6,replace=FALSE)
inters <- replicate(es,length(intersect(sample(nr_49,6,replace=FALSE),lucky)),simplify="array")
aux <- array(table(inters))
# There are situations in which at one step "i", there are no intersections of cardinal 5 or 6.
if(length(aux)==5)
{
aux <- c(aux,0,0)
}
else{
if(length(aux)==6)
{
aux <- c(aux,0)
}
}
table_1 <- table_1+aux
}
table_1 <- table_1/nr_esantion
我对得到的结果很满意,但我的问题是,对于 10^6$ 的门票,一次迭代大约需要 20 秒。因此总共 30 次迭代大约需要 10 分钟。对于某些项目任务,我必须将“nr_esantion”更改为 300。
我的问题:是否有更快的方法来计算这些 $10^6 * 300$ 样本?
library(parallel)
nr_esantion <- 30
es <- 10^6
nr_49 <- 1:49
table_1 <- integer(7) # Initialize table with integer values for better performance
# Pre-generate all the random tickets once as this does not change in the loop
all_tickets <- matrix(sample(nr_49, es * 6, replace = TRUE), ncol = 6, byrow = TRUE)
# Sample the lucky ticket outside the loop
lucky_ticket <- sample(nr_49, 6, replace = FALSE)
# Parallel processing setup
library(parallel)
cl <- makeCluster(detectCores() - 1) # Leave one core free for system processes
clusterExport(cl, varlist = c("all_tickets", "lucky_ticket", "nr_49", "es")) # Export variables to each node
clusterEvalQ(cl, {library(methods)}) # Load any required packages on each node
system.time({
# Use parSapply for parallel computation
results <- parSapply(cl, 1:nr_esantion, function(x) {
# The lucky ticket does not change, so intersect with all pre-generated tickets
intersections <- apply(all_tickets, 1, function(ticket) {
length(intersect(ticket, lucky_ticket))
})
# Tabulate the results
tabulate(intersections + 1, nbins = 7)
})
stopCluster(cl) # Stop the cluster after computation is done
})
table_1 <- colSums(results) / nr_esantion
table_1
这是一种可能性。
-我在进入循环之前预先生成了所有随机票。 - 幸运券在 nr_esantion 循环之外采样一次。 -我利用并行计算将工作分配到多个核心上。 -将每次迭代的结果制成表格,然后在循环外求和,从而减少开销。
请记住,并行处理在进程之间的设置和通信方面有一些开销,因此它对于大量计算最有效,这似乎就是您的情况。