サイコロを三回振った場合の模擬実験 [C++]
C++の組み込み関数rand()で、サイコロの目(0~5の乱数)を作成するには、
int w = rand() % 6;
と、すればよいのですが、その値に偏りがあるのか、プログラムを書いてみました。
計算回数は、6^3 * 1000000=216000000回です。
───〔出力例〕───────────────────────────
[1]____1_______2_______3_______4_______5_______6___
[1]:1000543|0999469|1000252|0999672|1002675|0998712|
[2]:1001618|0999092|0998974|0998730|1000177|1001213|
[3]:0999256|1001065|1000791|1000629|1000815|0999911|
[4]:0997926|1000197|1000881|1000440|1000317|0999886|
[5]:1000084|1000111|0998500|1000794|0999846|0999812|
[6]:0999941|1000783|0999410|1000617|1000006|1000962|
[2]____1_______2_______3_______4_______5_______6___
[1]:0998960|1000027|1001734|1001291|0998891|0999684|
[2]:1000086|1001278|0999235|1000509|1001512|0998860|
[3]:1001303|1000760|0999942|1000351|1000452|0999881|
[4]:1001625|1003014|1000614|0999743|0998704|0998420|
[5]:1000549|0998289|1000155|1000337|0999790|1000348|
[6]:0999838|1000325|0999819|1000846|1000591|1000457|
[3]____1_______2_______3_______4_______5_______6___
[1]:0999427|1000355|1002348|0998576|1001609|1001609|
[2]:0999696|0998271|0999960|0999242|0999911|1002712|
[3]:0999672|1001975|1000274|0999899|0998973|0999615|
[4]:1000761|0998979|0999601|0999118|0999395|0998472|
[5]:0999878|0998016|0999224|0998879|1000062|0999831|
[6]:1000029|1000100|1000177|1000790|0999268|1000379|
[4]____1_______2_______3_______4_______5_______6___
[1]:0999676|1001113|1000768|0999742|1001194|0999070|
[2]:0999310|1000612|0999664|0998667|0998773|1000450|
[3]:1001441|1000273|0999568|0998131|0999022|0999944|
[4]:0998711|0999256|0999807|0998127|0999040|1000966|
[5]:0999568|1001304|0999405|0999260|1000820|1000115|
[6]:0999976|1000501|1001026|0999794|1001223|1002006|
[5]____1_______2_______3_______4_______5_______6___
[1]:1000909|1000437|0999209|1000536|1001188|1000488|
[2]:0999808|0998888|0999973|0999404|1000137|0999498|
[3]:1000293|0999816|1000983|0999147|1000576|0999719|
[4]:0999514|0999723|0999846|1000552|1000585|1000949|
[5]:1000611|1000109|0998565|1000585|1000000|0998576|
[6]:1000988|1000158|0999036|0998985|0998768|1000254|
[6]____1_______2_______3_______4_______5_______6___
[1]:0998434|1000282|0999200|0999825|0999876|1000138|
[2]:1001494|1001926|1000407|0999839|1000990|0999508|
[3]:0999915|0999429|0998975|0999222|0999056|0999863|
[4]:1000062|1001049|0999962|0999183|0998720|1002047|
[5]:0999519|1000414|1001113|0998289|0999034|0999296|
[6]:0999764|0998878|0999041|1000338|0998348|1000018|
Max=1003014 Min=997926 (10.188 秒 2.12014e+07 回/秒)
──────────────────────────────
期待される数値は、それぞれの組合せで1000000ですが、最多で1003014回、最少で997926回という結果になりました(もちろん乱数ですから、模擬実験を行う度に結果の数字は少しずつ変動します)。
プラス約0.3%、マイナス約0.2%の範囲に収まっていますので、この乱数の組み込み関数rand()でプログラムすれば、偏りが気にならないサイコロの目をプログラムできると思います。
(by 心如)
───〔プログラム例〕───────────────────────────
// 2012.04.20 ───── coded by 心如
#include <iostream>
using namespace std;
//経過時間の取得
inline float getSec(){
return ((float)std::clock() / CLOCKS_PER_SEC);
}
const Mxn = 6;
const Kai = 1000000;
int main(){
int da[Mxn][Mxn][Mxn] = {0};
srand(time(NULL)); //乱数の初期化
int cnt = 0;
float fv = getSec(); //開始時刻
for(int i = 0;i < Mxn * Mxn * Mxn * Kai; i++){
da[rand() % Mxn][rand() % Mxn][rand() % Mxn] += 1;
cnt++;
}
fv = getSec() - fv; //経過時間
int max = 0;
int min = Kai;
for(int i = 0; i < Mxn; i++){
cout << "[" << i + 1;
cout << "]____1_______2_______3_______4_______5_______6___\n";
for(int j = 0; j < Mxn; j++){
cout << "[" << j + 1 << "]:";
for(int k = 0; k < Mxn; k++){
int n = da[j][i][k];
printf("%07d|", n);
if(max < n) max = n;
if(min > n) min = n;
}
cout << endl;
}
cout << endl;
}
cout << "Max=" << max;
cout << " Min=" << min;
cout << " (" << fv << " 秒 ";
cout << cnt / fv << " 回/秒)\n";
}
コメント 0