R

时间:2018-12-16 18:12:49

标签: r montecarlo

我从Msc开始学习R软件包,但是我在练习中遇到了问题。练习是这样的:

“假设我们要使用基本的蒙特卡洛方法来估计∫x2(在1到0之间确定)。本质上,我们将飞镖扔到曲线上并计算落在曲线下方的飞镖的数量。方法包括:

1)初始化:hits = 0

2)(1:N中的i):  生成两个随机数U1,U2,介于0和1之间。如果U2 <(U1)^ 2,则hits = hits + 1结尾。

3)区域估计=点击次数/ N

使用循环提供R代码以实现此Monte-Carlo算法。您的功能需要多少时间?提供更有效的代码,避免前面的循环。说明通过矢量化代码可以提高的效率。”

我有这些代码,但我认为我做错了。

montecarlo <- function(N){
  hits=0
  for (i in 1:N){
    U1 <- runif(1, 0, 1)
    U2 <- runif(1, 0, 1)
    if (U2 < (U1)^2){
      hits = hits+1}}
  return(hits/N)
}

montecarlo2 <- function(N){
  hits=0
  U1 <- runif (1:N, 0, 1)
  U2 <- runif (1:N, 0, 1)
  hits= hits+1 [U2<(U1)^2]
  return(hits/N)
}

对于第一个带有循环的方法,我已经获得(例如):

> montecarlo(23)
[1] 0.3478261
> montecarlo(852)
[1] 0.3591549
> montecarlo(8563255)
[1] 0.3332472

你能帮我吗?非常感谢:

2 个答案:

答案 0 :(得分:5)

其中一种方式:

montecarlo_for <- function(N) {
  hits <- 0
  for (i in 1:N) {
    U1 <- runif(1)
    U2 <- runif(1)
    if (U2 < (U1) ^ 2) hits <- hits + 1
  }
  return(hits / N)
}

矢量化

montecarlo_vec <- function(N) {
  sum(runif(N) < runif(N)^2) / N
}

例如使用microbenchmark软件包比较速度:

microbenchmark::microbenchmark(times = 50,
  montecarlo_for(1e5),
  montecarlo_vec(1e5)
)

我的机器上的速度比较显示,向量化方法大约快100倍(平均和中值时间如下所示):

Unit: milliseconds
expr                  mean       median
montecarlo_for(1e+05) 509.927001 497.238904
montecarlo_vec(1e+05) 5.214527   4.922007

只是为了好玩,如果您想看看算法随着样本数量的增加收敛到结果(1/3)的速度有多快:

plot(sapply(1:1000, montecarlo_vec), type = "line")

答案 1 :(得分:1)

这是我发现有助于估计积分的一种方法。请考虑以下内容:

因此,如果我们在支撑A上有一个分布G,那么我们可以用分布G中的样本估计f(x)在A上的积分。函数f不必严格为正。

在您的情况下,让X均匀分布,然后

因为支撑中的所有x的g(x)= 1。所以你可以用

来估计积分
N = 100000
mean(runif(N)^2)

您还可以让X为beta随机变量,并使用来估计积分

x = rbeta(N, 2, 1)
fx = x^2
gx = dbeta(x, 2, 1)
mean(fx / gx)

这是在正实线上估算函数的另一个示例。

f = function(x)
    abs(sin(x)) / (x+1)^2
x = rgamma(N, 2, 1/4)
fx = f(x)
gx = dgamma(x, 2, 1/4)
mean(fx / gx)

我不记得所有理论(何时使用这种方法可能会有一些限制),但是通常,如果您可以在与积分相同的支持下从任何分布中进行抽样,则可以估算出积分如上。而且,如果您选择的G的密度与函数f更加“接近”,则您的蒙特卡洛误差就越小。