【C#】正規分布に従う乱数の取得

.NETでは乱数のクラスにRamdomクラスがあります、どれも一様に分布する乱数しか取得できません。

例えば、NextDoubleメソッドを用いると、0以上、1.0未満の一様に分布した乱数を取得する事ができます。

var rnd = new Random();

for (int i = 0; i < 1000; i++)
{
    Console.WriteLine(rnd.NextDouble().ToString());
}

上記プログラムで出力した値をExcelでヒストグラムにしてみると、0~1.0の一様??な乱数が取得させていることが分かります。

C# 正規分布に従う乱数の取得

正規分布に従う乱数を取得するには、今回はボックス=ミュラー法という手法で乱数をしてみます。

XとYがお互いに独立で、0~1の範囲で一様に分布する乱数のとき

$${ Z }_{ 1 }=\sqrt { -2\log { X } } cos(2\pi Y)\\ { Z }_{ 2 }=\sqrt { -2\log { X } } sin(2\pi Y)$$

のZ1、Z2はそれぞれ標準偏差1.0、平均値0.0の正規分布に従う乱数となります。

(参考)ボックス=ミュラー法 Wikipedia

https://ja.m.wikipedia.org/wiki/%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%EF%BC%9D%E3%83%9F%E3%83%A5%E3%83%A9%E3%83%BC%E6%B3%95

これをC#のプログラムにしてみると

var rnd = new Random();

double X, Y;
double Z1, Z2;

for (int i = 0; i < 1000; i++)
{
    X = rnd.NextDouble();
    Y = rnd.NextDouble();

    Z1 = Math.Sqrt(-2.0 * Math.Log(X)) * Math.Cos(2.0 * Math.PI * Y);
    Z2 = Math.Sqrt(-2.0 * Math.Log(X)) * Math.Sin(2.0 * Math.PI * Y);

    Console.WriteLine(Z1.ToString());
    Console.WriteLine(Z2.ToString());
}

という感じ。

コンソールに吐き出された値をExcelでヒストグラムにしてみると

C# 正規分布に従う乱数の取得

となり、確かに正規分布に従った感じの分布となりました。
標準偏差1.0、平均値0.0ではなく、標準偏差sigma、平均値ave のときの乱数が欲しい場合は

Z1 = sigma * Math.Sqrt(-2.0 * Math.Log(X)) * Math.Cos(2.0 * Math.PI * Y) + ave;
Z2 = sigma * Math.Sqrt(-2.0 * Math.Log(X)) * Math.Sin(2.0 * Math.PI * Y) + ave;

となります。

← C#へ戻る

シェアお願いします

  • このエントリーをはてなブックマークに追加
関連記事

関連記事

関連記事
スポンサーリンク

同一カテゴリ人気記事