SICPを読む(94) 問題 3.5 - モンテカルロ法による定積分

出ました。セキブン。

問題 3.5

モンテカルロ法を使って、定積分せよという問題。前前回の応用編。

  • まず、x1,x2,y1,y2という範囲を設定する。x1 < x2, y1 < y2と限定しておく。
  • 範囲x1〜x2までの範囲をランダムにプロットしたいので、0〜1 * (x1 - x2) - x1として、x1〜x2を作る。
  • f(x1〜x2)をすると、fの結果が出るので、プラスかマイナスか選択。
  • fの結果とy1〜y2でプロットした範囲と比べる。
  • 範囲に置かれた点の比と面積比で比べる


円周率より断然めんどい。

(define (monte-cario-integral f x1 x2 y1 y2 n)
  (letrec ((put (lambda (s e) (+ (* (rand) (- e s)) s)))
           (iter (lambda (m count)
                   (if (zero? m)
                       (* (/ count n) (* (- x2 x1) (- y2 y1)))
                       (iter (- m 1)
                             (+ count
                                (let ((y (f (put x1 x2))))
                                     (if ((if (positive? y) <= >=)
                                          (put y1 y2) y)
                                         1
                                         0))))))))
          (iter n 0)))

テスト

y = x

∫0〜1 x

(monte-cario-integral values 0.0 1.0 0.0 1.0 1000) ; 0.492


円周率

2∫-1〜1 sqrt(1 - x^2)

(* 2 (monte-cario-integral (lambda (x)
                             (sqrt (- 1 (* x x)))) -1.0 1.0 0 1.0 1000)) ; 3.12


結果を見てわかることは、普通に積分したほうがいいってこと。


役には立たないけど、確率論で面積を測ろうと思った人は天才だと思うよ。


お、画像処理なんかなら、使えるかもしれないと思った。

例えば、モザイク処理をかけたいと思った時に、全ピクセルの平均値を取るより、ランダムに選んだ点の平均値を取ったほうが断然早い。「だいたいこんなもん」という感じで数値が取れればいいと思った時は有効に使えるかもしれない。

画像認識なんかで使ったら面白いだろうなぁと思った。