如何从整数范围生成正态分布随机数? [英] How to generate normally distributed random from an integer range?

查看:33
本文介绍了如何从整数范围生成正态分布随机数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个整数范围的开始和结束,我如何计算这个范围之间的正态分布随机整数?

Given the start and the end of an integer range, how do I calculate a normally distributed random integer between this range?

我意识到正态分布进入 -+ 无穷大.我猜尾巴可以被截断,所以当随机计算超出范围时,重新计算.这提高了该范围内整数的概率,但只要这种影响是可以容忍的(<5%),就可以了.

I realize that the normal distribution goes into -+ infinity. I guess the tails can be cutoff, so when a random gets computed outside the range, recompute. This elevates the probability of integers in the range, but as long as the this effect is tolerable (<5%), it's fine.

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

我可能需要将标准偏差相对于范围进行一些缩放,但不明白如何.

I probably need to scale the standard deviation some how relative to the range, but don't understand how.

答案:

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

推荐答案

如果 Box-Muller 方法返回一个标准"正态分布,它的平均值为 0,标准差为 1.要转换一个标准正态分布,你可以乘以你的随机数乘以 X 得到标准差 X,如果我没记错的话,你加上 Y 得到平均 Y.

If the Box-Muller method returns a "standard" normal distribution, it will have mean 0 and standard deviation 1. To transform a standard normal distribution, you multiply your random number by X to get standard deviation X, and you add Y to obtain mean Y, if memory serves me correctly.

请参阅 维基百科文章中关于标准化标准正态变量(属性 1) 的部分更正式的证明.

See the Wikipedia article's section on normalizing standard normal variables (property 1) for a more formal proof.

根据您的评论,经验法则是 99.7% 的正态分布将在标准偏差的 +/- 3 倍范围内.例如,如果您需要从 0 到 100 的正态分布,那么您的平均值将是一半,您的 SD 将是 (100/2)/3 = 16.667.因此,无论您从 Box-Muller 算法中得到什么值,乘以 16.667 以拉伸"分布,然后加上 50 使其居中".

In response to your comment, the rule of thumb is that 99.7% of a normal distribution will be within +/- 3 times the standard deviation. If you need a normal distribution from 0 to 100 for instance, than your mean will be halfway, and your SD will be (100/2)/3 = 16.667. So whatever values you get out of your Box-Muller algorithm, multiply by 16.667 to "stretch" the distribution out, then add 50 to "center" it.

John,针对您的最新评论,我真的不确定 Next 函数的意义何在.它始终使用 1 的标准差和最小值和最大值之间的平均值.

John, in response to your newest comment, I'm really not sure what is the point of the Next function. It always uses a standard deviation of 1 and a mean of halfway between your min and max.

如果您想要 Y 的平均值,大约 99.7% 的数字在 -X 到 +X 范围内,那么您只需调用 BoxMuller(Y, X/3).

If you want a mean of Y, with ~99.7% of the numbers in the range -X to +X, then you just call BoxMuller(Y, X/3).

这篇关于如何从整数范围生成正态分布随机数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆