JavaScriptで「偏りランダム」を行う方法
プログラムでランダムに値を変えるという場面はよくあります。
JavaScriptならば次のようにします。
血液型("A", "O", "B", "AB")からランダムに一つ取り出すサンプルです。
arrs = ["A", "O", "B", "AB"];
r = Math.floor(Math.random() * 4);
v = arrs[r];
r = Math.floor(Math.random() * 4);
v = arrs[r];
この場合、各血液型が均等に返ります。
しかし実際は血液型にはばらつきがあります。
日本人の場合、"A","O","B","AB"の順に4:3:2:1と言われています。
このように、頻度の異なる状況を反映したランダムを行う方法を考えました。
function random_frequency(recs) {
var recs_length, new_recs, i, j;
sum = 0;
recs_length = recs.length;
new_recs = [];
for(i = 0; i < recs_length; i++) {
for(j = 0; j < recs[i][1]; j++) {
new_recs.push(recs[i][0]);
}
}
r = Math.floor(Math.random() * new_recs.length);
return new_recs[r];
}
var recs_length, new_recs, i, j;
sum = 0;
recs_length = recs.length;
new_recs = [];
for(i = 0; i < recs_length; i++) {
for(j = 0; j < recs[i][1]; j++) {
new_recs.push(recs[i][0]);
}
}
r = Math.floor(Math.random() * new_recs.length);
return new_recs[r];
}
recsには要素と割合を指定します。日本人の血液型ならば次のようにします。
recs = [
["A", 4],
["O", 3],
["B", 2],
["AB", 1]
];
["A", 4],
["O", 3],
["B", 2],
["AB", 1]
];
サンプルを示します。
var recs, ct, i, v, rets;
recs = [
["A", 4],
["O", 3],
["B", 2],
["AB", 1]
];
ct = {
"A": 0,
"O": 0,
"B": 0,
"AB": 0
};
for(i = 0; i < 10000; i++) {
v = random_frequency(recs);
ct[v]++;
}
rets = [];
for(i = 0; i < recs.length; i++) {
v = recs[i][0];
rets.push(v + "=" + ct[v]);
}
alert(rets.join(" : "));
recs = [
["A", 4],
["O", 3],
["B", 2],
["AB", 1]
];
ct = {
"A": 0,
"O": 0,
"B": 0,
"AB": 0
};
for(i = 0; i < 10000; i++) {
v = random_frequency(recs);
ct[v]++;
}
rets = [];
for(i = 0; i < recs.length; i++) {
v = recs[i][0];
rets.push(v + "=" + ct[v]);
}
alert(rets.join(" : "));
実行したところ「A=3897 : O=3043 : B=2048 : AB=1012」になりました。
概ね4:3:2:1になっています。
[ 2015年8月29日 | カテゴリー: JavaScript | タグ: アルゴリズム , ランダム ]
« iPhoneのロック中にSiriが答えないようにする方法 | 大量のサンプルデータを作る「日本語ダミーデータ生成器」 »
コメントを残す