加快蒙特卡洛模拟?

时间:2018-07-24 21:10:39

标签: r for-loop iteration simulation montecarlo

我目前正在进行研究,以通过使用蒙特卡洛模拟法来预测葛根(一种侵入性葡萄树)将在五年内在俄克拉荷马州的何处传播。我已经创建了一个带有存在点的栅格,并将其加载到R中。

对于每个蒙特卡洛模拟(每年),我正在运行6000次迭代以提供准确的结果。但是,由于“ for”循环,这需要很长时间。第一年通常会在3天内完成运行,但是第二年已经运行了3周以上,但仍未完成。

有什么方法可以加快这个过程吗?

每年都是前一年的基础。我已经提供了前两年的以下代码:

OK.rast16<-raster("OK_rast20161.tif")
p.a16<-as.matrix(OK.rast16)
table(p.a16)

# Set the random number seed so results can be reproduced if needed
set.seed(10)

drow.pa16 <- 133.7197873 # distance of grid cell (meters) in n-s direction
trow.pa16 <- length(p.a16[,1]) # total number of rows

dcol.pa16 <- 133.7197873 # distance of grid cell (meters) in e-w direction
tcol.pa16 <- length(p.a16[1,]) # total number of rows

#####Year 1 of infection in 2016#####

kudzu_sim1_16 <- matrix(0,trow.pa16,tcol.pa16)
for(m in 1:6000)
{
  OK.kudzu_16 <- p.a16 # initialize matrix of annual dispersal
  for(i in 1:trow.pa16)
{
  for(j in 1:tcol.pa16)
{
  if(!is.na(p.a16[i,j]) & p.a16[i,j] == 1)
  {
    for(k in 1:trow.pa16)
    {
      for(l in 1:tcol.pa16)
      {
        if(!is.na(OK.kudzu_16[k,l]) & OK.kudzu_16[k,l] == 0)
        {
          distcalc <- sqrt((abs(i-k)*drow.pa16)^2+(abs(j-l)*dcol.pa16)^2)
          prob <- exp(0.0369599-0.00474401*distcalc)
          if(prob>runif(1)) {OK.kudzu_16[k,l] <- 1}
        }
      }
    }
   }
  }
 }
 kudzu_sim1_16 <- OK.kudzu_16+kudzu_sim1_16
}

#####Year 2 of infection in 2016####

kudzu_sim2_16 <- matrix(0,trow.pa16,tcol.pa16)
for(m in 1:6000)
{
  OK.kudzu1_16 <- OK.kudzu_16 # initialize matrix of annual dispersal
   for(i in 1:trow.pa16)
  {
    for(j in 1:tcol.pa16)
   {
     if(!is.na(OK.kudzu_16[i,j]) & OK.kudzu_16[i,j] == 1)
  {
    for(k in 1:trow.pa16)
    {
      for(l in 1:tcol.pa16)
      {
        if(!is.na(OK.kudzu1_16[k,l]) & OK.kudzu1_16[k,l] == 0)
        {
          distcalc <- sqrt((abs(i-k)*drow.pa16)^2+(abs(j-l)*dcol.pa16)^2)
          prob <- exp(0.0369599-0.00474401*distcalc)
          if(prob>runif(1)) {OK.kudzu1_16[k,l] <- 1}
        }
      }
    }
  }
 }
}
kudzu_sim2_16 <- OK.kudzu1_16+kudzu_sim2_16
}

以下是要加载以启动代码的栅格:

kudzu in OK

1 个答案:

答案 0 :(得分:0)

最初是评论,但很快超过了长度限制:

1)133mx133m是一个非常小的网格,用于在整个状态下进行空间模拟。这可能有助于找到一种方法,使分辨率成为仿真的参数(而不是硬连线的数字),简化代码,使其在较大的分辨率下运行良好,然后提高分辨率。 raster函数具有一个名为res的可选参数,可用于控制分辨率。

2)虽然矢量化肯定会有所帮助,但不太可能将运行数周且无输出的算法转换为在合理的时间内运行的算法。也许您需要从根本上重新考虑算法。您似乎正在将每个网格单元与其他所有网格单元进行比较。从生物学上看,这并不使我感到惊讶。葛根在当地传播。为什么明年对俄克拉荷马州黑手党一个给定的133m x 133m牢房会发生什么情况,取决于特克斯马湖附近另一个牢房的现状?如果您的模拟具有任何生物现实性,则exp(0.0369599-0.00474401*distcalc)对于两个这样的单元格应该可以忽略不计,但是您的代码不会忽略它。从某种意义上讲,本地化的算法可能会更好。

3)矩阵中有很多条目与俄克拉荷马州外的点相对应。除非您的模型旨在了解野葛还如何在得克萨斯州的大部分地区扩散,否则这些可能与您的程序无关。如果是这样,则最好采用根本不同的数据结构(例如位置列表),该数据结构仅在俄克拉荷马州具有点条目。或者可能不是。只是要考虑的事情。

4)要获得更详细的帮助,如果您解释算法的真正含义(而不仅仅是它的意图),将会有所帮助。快速阅读代码并不完全清楚。