Comment générer normalement distribuées de façon aléatoire à partir d'un nombre entier de gamme?

Donné le départ et la fin d'un intervalle entier, comment dois-je calculer une distribution normale entier aléatoire entre cette gamme?

Je me rends compte que la distribution normale va en+ l'infini. Je suppose que les queues peuvent être de coupure, de sorte que, lorsqu'un hasard obtient calculée en dehors de la plage, recalculer. Cela élève la probabilité d'entiers dans la gamme, mais tant que cet effet est tolérable (<5%), c'est la fin.

public class Gaussian
{
    private static bool uselast = true;
    private static double next_gaussian = 0.0;
    private static Random random = new Random();

    public static double BoxMuller()
    {
        if (uselast) 
        { 
            uselast = false;
            return next_gaussian;
        }
        else
        {
            double v1, v2, s;
            do
            {
                v1 = 2.0 * random.NextDouble() - 1.0;
                v2 = 2.0 * random.NextDouble() - 1.0;
                s = v1 * v1 + v2 * v2;
            } while (s >= 1.0 || s == 0);

            s = System.Math.Sqrt((-2.0 * System.Math.Log(s)) / s);

            next_gaussian = v2 * s;
            uselast = true;
            return v1 * s;
        }
    }

    public static double BoxMuller(double mean, double standard_deviation)
    {
        return mean + BoxMuller() * standard_deviation;
    }

    public static int Next(int min, int max)
    {
        return (int)BoxMuller(min + (max - min) / 2.0, 1.0); 
    }
}

J'ai probablement besoin à l'échelle de l'écart-type d'une façon relative par rapport à la plage, mais ne comprennent pas comment.

Réponse:

    //Will approximitely give a random gaussian integer between min and max so that min and max are at
    //3.5 deviations from the mean (half-way of min and max).
    public static int Next(int min, int max)
    {
        double deviations = 3.5;
        int r;
        while ((r = (int)BoxMuller(min + (max - min) / 2.0, (max - min) / 2.0 / deviations)) > max || r < min)
        {
        }

        return r;
    }

OriginalL'auteur | 2009-08-20