Microsoft Connect에서 이러한 기능에 대한 요청을 작성했습니다. 이것이 당신이 찾고있는 것이라면 투표하고 가시성을 높이십시오.
https://connect.microsoft.com/VisualStudio/feedback/details/634346/guassian-normal-distribution-random-numbers
이 기능은 Java SDK에 포함되어 있습니다. 구현은 설명서의 일부로 제공 되며 C # 또는 기타 .NET 언어로 쉽게 이식됩니다.
순수한 속도를 찾고 있다면 Zigorat 알고리즘 이 일반적으로 가장 빠른 접근 방식으로 인식됩니다.
하지만 저는이 주제에 대한 전문가는 아닙니다. RoboCup 3D 시뮬레이션 로봇 축구 라이브러리에 입자 필터 를 구현하는 동안 이것이 필요하다는 것을 알게 되었고 이것이 프레임 워크에 포함되지 않았을 때 놀랐습니다.
한편, Random
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;
}
}