c# - 使用 box-muller 方法生成随机标准正态分布数
问题描述
我需要生成介于 0 和 1 之间的随机标准正态分布数,均包含在均值 0 和标准开发 1 中。问题是虽然代码正在工作,但生成的随机数不在 0 和 1 之间。
这是使用 Box-muller 算法的方法:
public double NextGaussian()
{
double u1 = r.NextDouble();
double u2 = r.NextDouble();
double left = Math.Cos(2.0 * Math.PI * u1);
double right = Math.Sqrt(-2.0 * Math.Log(u2));
double z = left * right;
return this.mean + (z * this.standardDeviation);
}
然后在main方法中:
Gaussian g = new Gaussian(0.0, 1.0);
double a = g.NextGaussian();
我希望变量 a 的值都在 0 和 1 之间,但实际输出都是数字
解决方案
我认为您的问题在于对正态分布的误解。正态分布为您提供范围内的数字(-inf, inf)
。虽然绝对值越大,这个数字就越不可能(不是线性的)。您可以在正态分布的每张图片上看到这一点。简而言之,平均值是最高概率的值,标准偏差定义了曲线的峰值程度,
由于您只需要[mean, mean + standard dev]
i 中的值,因此建议稍微调整分布并使用随机数的绝对值(相对于均值)并将其切割为标准偏差,将此值视为mean + standart dev
.
public static double NextRandomWithinStandardDeviation(this Gaussian gaussian)
{
return Math.Min(
Math.Abs(gaussian.NextRandom() - gaussian.Mean) + gaussian.Mean,
gaussian.Mean + gaussian.StandardDeviation
);
}
然而,这不会是真正的正态分布。事实上,所有生成的随机数中有 21.73% 会超出您的区间,这会提高获得mean + standard deviation
显着的概率。
另一种方法可能是生成随机数,直到生成的数字在区间内。理论上这可能需要很长时间,但在第五次迭代后得到一个超出区间的数字的概率小于 0.01%。
public static double NextRandomWithinStandardDeviation(this Gaussian gaussian)
{
double randomNumer;
do
{
randomNumber = Math.Abs(gaussian.NextRandom() - gaussian.Mean) + gaussian.Mean;
}while(randomNumber > gaussian.Mean + gaussian.StandardDeviation);
return randomNumber;
}
推荐阅读
- html - CSS:在另一个动画期间更改div的颜色
- java - 我可以以某种方式将实体映射到休眠状态并在属性的 getter 中具有条件逻辑吗?
- r - 在 x 列中查找重复项,然后删除 y 列中具有较低值的行
- c# - 从asp.net mvc中的数据库检索数据时如何获取日期而不获取时间
- javascript - 无法在本机反应中使用堆栈导航器
- javascript - 如何在 Javascript 中的 Where() 方法中放置变量?
- uwp - UWP InAppNotification
- python - 如何使用python将一列excel中的数据拆分为多列
- elasticsearch - 运行弹性搜索复合聚合时出现“未知 BaseAggregationBuilder [复合] 错误”
- android - 如何将微调器选择的值传递给同一活动中的 onCreate() 部分?