Montecarlo法を用いて円周率\(\pi\)の近似値を求める。

 

半径が\(r\)の円と、その円に外接する正方形の面積を考える。 円の面積は\(\pi r^{2}\)であり、正方形の面積は\(4r^{2}\)である。

これらの面積比を\(a\)として計算すると、\(a=\dfrac{\pi r^{2}}{4r^{2}}=\dfrac{\pi}{4}\)となる。

つまり、\(a\)の値を推定することで円周率を推定できる。

ここで、この正方形内にランダムに\(n\)個の点を打ち、そのうち円内部に入った点の個数を\(m\)とする。

このとき、円内部に点が打たれる確率は\(\dfrac{m}{n}\)である。

よって、\(\dfrac{\pi}{4}=\dfrac{m}{n}\)すなわち\(\pi=\dfrac{4m}{n}\)となる。

これによって円周率を推定することができる。

以下のプログラムでは簡単のため、円の半径を\(1\)とし、第一象限のみで考えるものとする。

montecarlo <- function(n){
  m <- 0 #円内部にある点の個数; 始めは0個とする
  cols <- NULL #plotする点に色をつけるためのもの
  range <- c(0,1) #範囲を第一象限とする
  x <- runif(n,0,1) #一様乱数でx座標を定める; runif(試行回数,開始値,終了値)
  y <- runif(n,0,1) #一様乱数でy座標を定める
  r <- x^2+y^2 #円の範囲
  for(i in r){ 
    if(i<=1){
      m <- m +1 #円内部であれば、円内部の点の個数を1つ増やす
      cols <- c(cols, "red") #更に赤色でプロットする
    } else{
      cols <- c(cols,"blue") #円外部であれば青色でプロットする
    }
  }
# forループは以下のようにも書ける
#  inner <- (r<=1)
#  m <- sum(inner)
#  cols <- ifelse(inner,"red","blue")
  return_data <- 4*m/n #円周率の計算
  plot(x,y,col=cols,xlim=range,ylim=range,asp=1)
  #点をプロットする,xとyの範囲は上で定めたもの,x軸とy軸の比率を1にする
  return(return_data)
}

\(n=1000\)として結果を出力すると、図と出力結果は以下である。

## [1] 3.088

また、\(n=10000\)として結果を出力すると結果は以下である。

## [1] 3.1456