意図的な偏り(傾向)付きの乱数を手軽に生成する
便利なライブラリ情報や 最新の動向系のエントリは 他の方が書きまくっていますので、私からは少し違う毛色のエントリを。
ウィジェット、ブログパーツ、或いはサイトFlashの全てにおいて出てくる、「表現」系のお話です。
ちょっとした表現を行おうとすると、例えば「座標」であったり「速度」であったり「角度」であったり「継続時間」であったり「縮尺」であったりの各パラメータに 乱数を使うことが多々あります。
さて、おなじみのMath.random()で生成した乱数というのは、(生成アルゴリズムのマズさから来る偏りという面を除けば)一様に分布します。
ですが、上で挙げたような いわゆる連続量に乱数を適用する際は、意図的な「偏り」というか「傾向」が欲しい場合も多いワケです。
例えば「大きい数の方が小さい数より出やすい」など。
これらを真面目に実装しようとすると、数学の時間にやった 確率密度関数などを復習する必要が出てくるワケですが、「数学キライー!」「だってボク☆文系だもん♪」という方のために、簡単に実装する方法を紹介いたします。
一言で言えば、
「普通に乱数を生成し、そこから “今生成した乱数を最大値とする乱数”を引く」ことで、小さい方に偏る乱数を生成できます。
…文章で説明してもややこしいので、以下コード例。
function inclinationalRandom (max :Number) :Number
{
var result :Number = Math.random();
result -= Math.random() * result;
return (result * max);
}
この方法で、「0以上 10未満」の乱数を8000回生成して適当に整数化した際の出現回数がこちら。
偏ってますねー。「小さい数が出やすい傾向を持った乱数」の生成、完了です。
しかしこれではいくら何でも偏り過ぎ!…という意見もあるでしょうから、もう少しマイルドにしてみましょう。
ついでに「マイルド度」も指定できるようにしてみましょう。
function inclinationalRandom (max :Number, rate :Number) :Number
{
var result :Number = Math.random();
var incl :Number = result - (Math.random() * result);
result = (result + (incl * rate)) / (1.0 + rate);
return (result);
}
基本的に先程のコードと考え方は同じなのですが
、「偏らせる(小さくい方へ引っ張る)ための数」に倍率を掛けています。
rateを弄ることで「偏り」を調節できます。
ちなみに離散量にも応用できるのですが、長くなっちゃいますのでまたの機会に。




