モンテカルロ法で円周率を求める
「モンテカルロ法を実装しなきゃ!」という気分になった。
まずモンテカルロ法がなんなのかわからんかったので、調べるところから。適当にぐぐった。「確率で積分がどうしたこうしてほげほげ」。よくわからんな。円周率を求めることができるらしい。なんか聞いたことあるねそれ! よくわからんまま適当にやってみよう。
マニュアルのstd.randomのページに「Cのrandよりランダム性高いよ!」と書いてあったので、Cのrandとphobosのrandを切り替えられるようにしてみた。
% repeat 5 (./pi 50000000 c) testNum=50000000, mode=c, pi=3.1419588000 testNum=50000000, mode=c, pi=3.1416315200 testNum=50000000, mode=c, pi=3.1417908000 testNum=50000000, mode=c, pi=3.1414636800 testNum=50000000, mode=c, pi=3.1417736000 % repeat 5 (./pi 50000000 phobos) testNum=50000000, mode=phobos, pi=3.1415154400 testNum=50000000, mode=phobos, pi=3.1416636000 testNum=50000000, mode=phobos, pi=3.1419204000 testNum=50000000, mode=phobos, pi=3.1416398400 testNum=50000000, mode=phobos, pi=3.1413786400
わーすげえや円周率っぽい!
うーん。っつーかこんなん、doubleとかintとかuintの長さとか、randの返す範囲とかそういうのも考慮に入れて考えなきゃいけないから、単純に「こっちのが円周率に近かったからよい擬似乱数!」って喜んでいいもん違うだろうし。以下ソース。
import std.stdio; import std.string; import std.random; import std.c.stdlib; import std.c.time; double getPi(int testNum, double function() random) { double pi = 0; int count = 0; for(int i=0;i<testNum;++i){ double x = random(); double y = random(); if(x*x+y*y <= 1) ++count; } return count/cast(double)testNum*4.0; } double phobosRand(){ double rand = std.random.rand(); rand /= uint.max; return rand; } // stdlib.hに書いてる値もってくる。 const int RAND_MAX = 2147483647; double cRand(){ double rand = std.c.stdlib.rand(); rand /= RAND_MAX; return rand; } double function() getRand(char[] type) { double function() random; if(type=="phobos"){ random = &phobosRand; } else if(type=="c"){ srand(cast(uint)time(null)); random = &cRand; } else{ random = &phobosRand; } return random; } int main(char[][] args) { if(args.length==1){ fwritefln(stderr, "usage: %s testNum [phobos|c]", args[0]); return 1; } int n = cast(int)std.string.atoi(args[1]); char[] type = args.length==3 ? args[2] : "phobos"; double function() random = getRand(type); writefln("testNum=%d, mode=%s,\t\tpi=%.10f", n, type, getPi(n, random)); return 0; }
べつにこれC言語でもほとんど同じに書けるなそういえば。あんましかっとんだ機能使わずにD言語で書くのは、C言語で書くプログラムのプロトタイプには良いのかもしれないなあ。