当前位置:  开发笔记 > 前端 > 正文

跟踪循环迭代

如何解决《跟踪循环迭代》经验,为你挑选了1个好方法。

抛硬币.成功,你赢了100,否则你输了50.你会继续玩,直到你的口袋里有钱a.如何a存储任何迭代的值?

a <- 100
while (a > 0) {
  if (rbinom(1, 1, 0.5) == 1) {
    a <- a + 100
  } else {
    a <- a - 50
  }
}

作为最终结果,当while循环结束时,我希望能够查看a每次迭代的值,而不仅仅是最终结果.我查阅了关于计算迭代次数的帖子,但我无法将其应用于此案例.



1> jbaums..:

将初始值存储a在第二个向量中,并a在每次迭代时附加新值.

a <- pocket <- 100
while (a > 0) {
  if (rbinom(1, 1, 0.5) == 1) {
    a <- a + 100
  } else {
    a <- a - 50
  }
  pocket <- c(pocket, a)
}

当然,矢量化方法可能更有效,例如:

n <- 1000000
x <- c(100, sample(c(100, -50), n, replace=TRUE))
cumsum(x)[1:match(0, cumsum(x))]

但是不能保证你会在n迭代中耗尽资金(在这种情况下你会收到一个错误,只能看看x实现的轨迹).


编辑

为了回应@Roland所表达的担忧,以下方法避免了在每次迭代时重新分配内存:

n <- 1e6
a <- rep(NA_integer_, n)
a[1] <- 100L # set initial value (integer)
i <- 1 # counter
while(a[i] > 0) {
  # first check whether our results will fit. If not, embiggenate `a`.
  if(i==length(a)) a <- c(a, rep(NA_integer_, n))
  if (rbinom(1, 1, 0.5) == 1) {
    a[i+1] <- a[i] + 100L
  } else {
    a[i+1] <- a[i] - 50L
  }
  i <- i + 1  
}
a[seq_len(i)]


@Worice - 我无法想到任何资源.上面的主要节省时间(至少对于大`n`)是使用`sample`.例如,对于`n < - 1e7`,`sample(0:1,n,replace = TRUE)`需要大约0.2秒,而`for(i in 1:n)sample(0:1,1)`大约需要24秒秒.我们称之为"样本"一次而不是1000万次.类似地,我们可以使用`rbinom(n,1,0.5)`(带有一些额外的后处理工作).矢量化操作可以非常频繁地替换循环,但知道何时何地主要是熟悉可用的函数(阅读函数文档).
@Worice [值得一读](http://www.noamross.net/blog/2014/4/16/vectorization-in-r--why.html); 作者还在文章末尾列出了关于矢量化的资源.
请不要在每次迭代时生成对象.如果您不知道最终大小,请预先分配一个猜测,如果它仍有足够的空间,则在每次迭代中进行测试,如果没有,则按块进行增长.
推荐阅读
围脖上的博博_771
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有