.NET的标准库中是否有一个类可以创建遵循高斯分布的随机变量的功能?
Jarrett建议使用Box-Muller变换对于快速而肮脏的解决方案是有益的.一个简单的实现:
Random rand = new Random(); //reuse this if you are generating many double u1 = 1.0-rand.NextDouble(); //uniform(0,1] random doubles double u2 = 1.0-rand.NextDouble(); double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2); //random normal(0,1) double randNormal = mean + stdDev * randStdNormal; //random normal(mean,stdDev^2)
这个问题似乎已经转移到谷歌的.NET高斯世代,所以我想我会发一个答案.
我为.NET Random类做了一些扩展方法,包括Box-Muller变换的实现.由于它们是扩展,只要包含项目(或者您引用已编译的DLL),您仍然可以
var r = new Random(); var x = r.NextGaussian();
希望没有人介意无耻的插头.
结果的样本直方图(包括用于绘制此结果的演示应用程序):
Math.NET提供此功能.这是如何做:
double mean = 100; double stdDev = 10; MathNet.Numerics.Distributions.Normal normalDist = new Normal(mean, stdDev); double randomGaussianValue= normalDist.Sample();
您可以在此处找到文档:http: //numerics.mathdotnet.com/api/MathNet.Numerics.Distributions/Normal.htm
我在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(); } ////// 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. /// /// The mean of the distribution. Default is zero. /// The standard deviation of the distribution. Default is one. ///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; } }
Math.NET Iridium还声称实现了"非均匀随机生成器(normal,poisson,binomial,...)".