58 votos

Aleatorio Gaussiano Variables

¿alguien de ustedes sabe si hay una clase en la biblioteca estándar de .net, que me proporciona la funcionalidad para crear variables aleatorias que siguen una distribución de gauss?

Saluda

Sebastián

89voto

yoyoyoyosef Puntos 2311

Jarrett sugerencia de utilizar un Box-Muller transformar es bueno para una rápida y sucia de la solución. Una implementación simple:

Random rand = new Random(); //reuse this if you are generating many
double u1 = rand.NextDouble(); //these are uniform(0,1) random doubles
double u2 = 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)

20voto

Superbest Puntos 3464

Esta pregunta parece que se han movido en la parte superior de Google .RED de Gauss generación, así que pensé en publicar una respuesta.

He hecho algunos métodos de extensión para el .RED de clase al Azar, incluyendo una aplicación de la Box-Muller transformar. Ya que son extensiones, siempre y cuando el proyecto se incluye (o se hace referencia a la DLL compilada), usted todavía puede hacer

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

Espero que nadie mentes el enchufe descarado.

Ejemplo de histograma de resultados (un demo de la aplicación para la elaboración de este incluido):

enter image description here

12voto

Jarrett Meyer Puntos 11147

http://mathworld.wolfram.com/Box-MullerTransformation.html

El uso de dos variables aleatorias, puede generar valores aleatorios a lo largo de una distribución de Gauss. No es una tarea difícil en absoluto.

6voto

Drew Noakes Puntos 69288

He creado una petición para una característica en Microsoft Connect. Si esto es algo que usted está buscando, por favor voten por ella y el aumento de su visibilidad.

https://connect.microsoft.com/VisualStudio/feedback/details/634346/guassian-normal-distribution-random-numbers

Esta característica está incluida en el SDK de Java. Su aplicación está disponible como parte de la documentación y puede ser portado fácilmente a C# u otro .NET languages.

Si usted está buscando para la velocidad pura, entonces la Zigorat Algoritmo es generalmente reconocido como el más rápido de enfoque.

Yo no soy un experto en este tema a pesar de que -- me encontré con la necesidad de este, mientras que la aplicación de un filtro de partículas para mi RoboCup simulado en 3D de fútbol robótico de la biblioteca y se sorprendió cuando este no estaba incluido en el framework.


En el mientras tanto, aquí hay un contenedor para Random que proporciona una implementación eficiente de la Caja Muller polar método:

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

5voto

Jason DeFontes Puntos 1702

Math.NET Iridium también pretende implementar "no-aleatorio uniforme generadores (normal, poisson, binomial, ...)".

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X