-2

这不是家庭作业,只是我的学习练习。我一直在 R 中运行一个非常简单的模拟(或数字曲柄)。它生成两个数字(A,B)并运行 1 个月。

A=NULL
B=NULL
x=NULL
x <- Sys.time()
duration <-  2592000 # 30 days
while(Sys.time() <= x + duration){
A <-append(A, sample(1:5, 1000, 1/5))
B <-append(B, sample(1:5, 1000, 1/5))
save.image()
}

我认为它进展顺利,但一周后(产生了数百万个数字),操作系统终止了该进程。有没有更好的方法来编写或运行模拟来防止操作系统杀死它?

我宁愿重写模拟而不是适应操作系统(例如添加更多交换等)。我在低功率设备(Raspberry Pi)上运行模拟,并且在硬件方面我能做的事情有限。谢谢。

更新:
1)一次生成1000个样本并不重要。这只是我的一团糟。
2)重要的模拟运行一段时间,即 1 周、1 个月或 1 年。
3)除非不可能,否则我想要原始数据。

4

2 回答 2

1

如果目标是创建两个大样本,请考虑以下事项:

N <- 2000000
A <- sample(1:5, N, 1/5)
B <- sample(1:5, N, 1/5)
save.image()

如果对于 A 和 B 一次形成 1000 个样本很重要,请考虑以下问题:

N <- 2000
n <- 1000
A.list <- vector("list", N)
B.list <- vector("list", N)
for (i in 1:N) {
   A.list[[i]] <- sample(1:5, n, 1/5) 
   B.list[[i]] <- sample(1:5, n, 1/5)
}
A <- unlist(A.list)
B <- unlist(B.list)
save.image()

这应该解决代码中的两个主要问题:

  • 每次append在循环中使用时,R 都必须从头开始创建和填充几个新对象。随着对象变大,你的循环迭代变得越来越慢;我相信计算时间是二次增长的。您还冒着内存空间碎片化的风险,这很难解释,但您可以尝试研究它。通过使用列表,只需将每次迭代的新数据存储到内存中,并且每次循环的计算时间保持不变。
  • 我已将 save.image() 移出循环。同样的想法,随着对象变得越来越大而保存对象将花费越来越长的时间,即减慢您的迭代速度。由于您只关心最终向量,因此仅在完成后保存才有意义。

您可以使用 的值N来查看您的操作系统会让您走多远。优点是您不必等待一周或一个月来找出限制。

于 2012-07-09T11:03:38.883 回答
1

如果您考虑将结果打印在纸上作为可接受的解决方案,那么 Roman Luštrik 将数据附加到文本文件或数据库的解决方案(在您的问题的评论中)绝对是一个很好的解决方案。

这是附加到文本文件的样子:

x <- Sys.time()
duration <-  2592000
while(Sys.time() <= x + duration){
    write.table(sample(1:5, 1000, 1/5),file="A.txt",append=TRUE,row.names=FALSE,col.names=FALSE,sep="\t")
    write.table(sample(1:5, 1000, 1/5),file="B.txt",append=TRUE,row.names=FALSE,col.names=FALSE,sep="\t")
}
于 2012-07-09T15:00:24.883 回答