Saya membuat permintaan untuk fitur seperti itu di Microsoft Connect. Jika ini adalah sesuatu yang Anda cari, silakan pilih dan tingkatkan visibilitasnya.
https://connect.microsoft.com/VisualStudio/feedback/details/634346/guassian-normal-distribution-random-numbers
Fitur ini termasuk dalam Java SDK. Implementasinya tersedia sebagai bagian dari dokumentasi dan dengan mudah diporting ke C # atau bahasa .NET lainnya.
Jika Anda mencari kecepatan murni, maka Algoritma Zigorat secara umum dikenal sebagai pendekatan tercepat.
Saya bukan ahli dalam topik ini - saya menemukan kebutuhan untuk ini saat menerapkan filter partikel untuk pustaka robot sepak bola simulasi RoboCup 3D saya dan terkejut ketika ini tidak termasuk dalam kerangka kerja.
Sementara itu, berikut adalah pembungkusnya Random
yang menyediakan implementasi yang efisien dari metode kutub Box Muller:
public sealed class GaussianRandom
{
private bool _hasDeviate;
private double _storedDeviate;
private readonly Random _random;
public GaussianRandom(Random random = null)
{
_random = random ?? new Random();
}
/// <summary>
/// Obtains normally (Gaussian) distributed random numbers, using the Box-Muller
/// transformation. This transformation takes two uniformly distributed deviates
/// within the unit circle, and transforms them into two independently
/// distributed normal deviates.
/// </summary>
/// <param name="mu">The mean of the distribution. Default is zero.</param>
/// <param name="sigma">The standard deviation of the distribution. Default is one.</param>
/// <returns></returns>
public double NextGaussian(double mu = 0, double sigma = 1)
{
if (sigma <= 0)
throw new ArgumentOutOfRangeException("sigma", "Must be greater than zero.");
if (_hasDeviate)
{
_hasDeviate = false;
return _storedDeviate*sigma + mu;
}
double v1, v2, rSquared;
do
{
// two random values between -1.0 and 1.0
v1 = 2*_random.NextDouble() - 1;
v2 = 2*_random.NextDouble() - 1;
rSquared = v1*v1 + v2*v2;
// ensure within the unit circle
} while (rSquared >= 1 || rSquared == 0);
// calculate polar tranformation for each deviate
var polar = Math.Sqrt(-2*Math.Log(rSquared)/rSquared);
// store first deviate
_storedDeviate = v2*polar;
_hasDeviate = true;
// return second deviate
return v1*polar*sigma + mu;
}
}