如何从整数范围生成正态分布随机?

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

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

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

我可能需要将标准差缩放一些相对于范围的方法,但不明白如何。

回答:

  // 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,如果记忆正确地为我服务。

有关更正式的证据,请参阅维基百科文章关于规范标准正态变量(属性1)的部分 。


根据您的评论,经验法则是99.7%的正态分布将在标准偏差的+/- 3倍之内。 例如,如果您需要从0到100的正态分布,那么您的平均值将是中途,并且您的SD将是(100/2)/ 3 = 16.667。 因此,无论你使用Box-Muller算法获得什么值,都要乘以16.667来“拉伸”分布,然后将50加到“中心”它。


John回应你的最新评论,我真的不确定Next函数的重点是什么。 它总是使用1的标准偏差和最小值和最大值之间的平均值。

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

那么,-2 * sigma .. + 2 * sigma会给你95%的钟形曲线。 (查看已经提到的wiki文章中的“标准偏差和置信区间”部分)。

所以修改这篇文章:

 return (int)BoxMuller(min + (max - min) / 2.0, 1.0); 

并将1.0(标准差)更改为2.0(如果您希望覆盖率超过95%,则更高)

 return (int)BoxMuller(min + (max - min) / 2.0, 2.0);