当前位置:  开发笔记 > 编程语言 > 正文

随机高斯变量

如何解决《随机高斯变量》经验,为你挑选了5个好方法。

.NET的标准库中是否有一个类可以创建遵循高斯分布的随机变量的功能?



1> yoyoyoyosef..:

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)


@Johann,如果你正在寻找纯粹的速度,那么[Zigorat算法](http://en.wikipedia.org/wiki/Ziggurat_algorithm)通常被认为是最快的方法.此外,通过携带从一个呼叫到下一个呼叫的值,可以使上述方法更快.
我对其进行了测试,并与MathNet的Mersenne Twister RNG和NormalDistribution进行了比较。您的版本的运行速度快两倍以上,并且最终结果基本相同(“铃铛”的外观检查)。

2> Superbest..:

这个问题似乎已经转移到谷歌的.NET高斯世代,所以我想我会发一个答案.

我为.NET Random类做了一些扩展方法,包括Box-Muller变换的实现.由于它们是扩展,只要包含项目(或者您引用已编译的DLL),您仍然可以

var r = new Random();
var x = r.NextGaussian();

希望没有人介意无耻的插头.

结果的样本直方图(包括用于绘制此结果的演示应用程序):

在此输入图像描述



3> Gordon Slysz..:

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



4> Drew Noakes..:

我在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;
    }
}



5> Jason DeFont..:

Math.NET Iridium还声称实现了"非均匀随机生成器(normal,poisson,binomial,...)".

推荐阅读
我我檬檬我我186
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有