何回コインを投げれば連続10回表が出るんだろう(4)

分布はだいたい分かったので、これで擬似乱数を調べてみよう。
100万回行って、得られた回数を100ごとに区切って、度数をみる。


VC2005EEで、rand()で得られた値の特定のビットを拾う。


if(rand() & bit) {
...

bitが1の結果は、

〜100 56000
〜200 24000
〜300 16000
〜400 32000

8000単位だから、125回周期で同じ回数になることがわかる。
しかし、これは予想外だった。
最下位ビットは非常に規則的に並ぶと思っていたから。
いまどき線形合同法じゃないのか。


それ以外に、5、10、14ビット目と、JScriptで0.5との比較でみてみた。

10ビットまではこのグラフで見ても誤差が大きいことが分かる。
では、14ビット目とJScriptではどちらがよいか、標準偏差でみてみた。

変わらないと言っていいだろう。結局同じなのかもしれない。精度もここまでならよいようだ。



#include
#include

using namespace std;

int play();
void increment(vector& ary, int m);

int bit;

void main(int argc, char **argv) {
if(argc != 2) {
cerr << "usage : coin4 bit." << endl;
exit(1);
}
bit = 1 << atoi(argv[1]);

const int N = 10;
vector count;
for(int i = 0; i < N; i++) {
increment(count, play());
}

for(int i = 0; i < (int)count.size(); i++) {
cout << (i + 1) * 100 << "," << count[i] << endl;
}
}

int play() {
const int n = 10;
int head = 0;
int counter = 0;
while(true) {
counter++;
if(rand() & bit) {
if(++head == n)
return counter;
}
else
head = 0;
}
}

void increment(vector& ary, int m) {
int k = (m - 1) / 100;
int size = (int)ary.size();
if(size <= k) {
ary.resize(k + 1);
for(int i = size; i <= k; i++)
ary[i] = 0;
}
ary[k]++;
}