今回のエンジニアブログを担当する加賀です。
高速な擬似乱数生成アルゴリズムのXorshiftを紹介したいと思います。
今回のコードはVisual Studio 2010 Pro SP1、C# 3.5で確認しています。
Xorshiftとは
Xorshiftとは、その名の通り、XOR(排他的論理和)とシフト演算のみを使用する乱数生成アルゴリズムです。
複雑な計算をしていないので、かなり高速に乱数を生成することが出来ます。
また、生成し続けて再び同じ数が出てくるまでの周期は2128-1と、精度も実用には悪くありません。
C# 実装例
public class Xorshift { // 内部メモリ private UInt32 x; private UInt32 y; private UInt32 z; private UInt32 w; public Xorshift () : this ((UInt64)DateTime.Now.Ticks) { } public Xorshift (UInt64 seed) { SetSeed (seed); } /// <summary> /// シード値を設定 /// </summary> /// <param name="seed">シード値</param> public void SetSeed (UInt64 seed) { // x,y,z,wがすべて0にならないようにする x = 521288629u; y = (UInt32)(seed >> 32) & 0xFFFFFFFF; z = (UInt32)(seed & 0xFFFFFFFF); w = x ^ z; } /// <summary> /// 乱数を取得 /// </summary> /// <returns>乱数</returns> public UInt32 Next () { UInt32 t = x ^ (x << 11); x = y; y = z; z = w; w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)); return w; } }
Nextメソッドを見て分かるように、乱数生成部分は非常にシンプルです。
シード値の設定部分は、結構適当です。
4つの内部メモリがすべて0にならないようにしておけばいいようです。
あとはここに範囲内の乱数取得や、浮動小数で乱数取得などを追加すれば十分使えるものが出来ます。
Xorshiftの実装例については、検索するといろいろと見つかります。
最後に
速度が必要で、厳密な精度を必要としないなら、Xorshiftが十分使えると思います。
また、乱数発生器を簡単に別インスタンスにできるので、ローグライクのような自動生成のゲームで
同じマップをもう一度生成したい場合なども簡単にできます。
これからも、このような便利なものを見つけて、使っていきたいです。