C#(.Net)での乱数は System.Random メソッドで発生させることが出来ます。
ところが、シード値を設定しない場合にはパソコンを起動してからの時間(ミリ秒)がシード値として設定される1)“Random クラスでシード値を指定せずにインスタンスを生成した場合、そのシード値には System.Environment クラスの TickCount プロパティが使用されます。 このプロパティは、PC を最後に起動してからの経過時間をミリ秒単位でかえす…”ため、場合によっては乱数を発生させたのにも関わらず同じ値が連続して発生されることがあります。
厳密な形で乱数を発生させたい場合には「System.Security.Cryptography」名前空間のRNGCryptoServiceProviderクラスで乱数を作成させるのが良いようです。
ここではRNGCryptoServiceProviderクラスを用いたdouble型の乱数発生の例として、一様乱数に加えて正規分布に従う乱数の発生のコードを貼り付けておきます。
//冒頭にはコレが必要 using System.Security.Cryptography; //…中略… /// <summary> /// 一様乱数を取得する /// </summary> /// <returns>乱数:-1~+1</returns> public static double GetRandom() { RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); byte[] bs = new byte[sizeof(Int32)]; rng.GetBytes(bs); int iR = System.BitConverter.ToInt32(bs, 0); return ((double)iR / Int32.MaxValue); } /// <summary> /// 標準正規分布に従う乱数 /// </summary> /// <returns>N(0,1)に従う乱数</returns> public static double GetNormRandom() { double dR1 = Math.Abs(GetRandom()); double dR2 = Math.Abs(GetRandom()); return (Math.Sqrt(-2 * Math.Log(dR1, Math.E)) * Math.Cos(2 * Math.PI * dR2)); } /// <summary> /// 正規分布(μ・σ)に従う乱数 /// </summary> /// <param name="m">平均:μ</param> /// <param name="s">標準偏差:σ</param> /// <returns>N(m,s)に従う乱数</returns> public static double GetNormRandom(double m, double s) { return (m + s * GetNormRandom()); }
この記事を書くにあたって下記のサイトを参考にさせて頂きました。
・DOBON.NET > 乱数を生成する
・C#でボックスミューラー法による正規分布に従う乱数生成