生成正态分布数的一种流行方法来自Kinderman和Monahan推导出的并由Leva改进的均匀偏差技术的比率。 The method is compact and requires little memory:
static Random r = new Random();
static double Normal(double mu, double sig)
{
double u, v, x, y, q;
do
{
u = r.NextDouble();
v = 1.7156 * (r.NextDouble() - 0.5);
x = u - 0.449871;
y = Math.Abs(v) + 0.386595;
q = Math.Sqrt(x) + y * (0.19600 * y - 0.25472 * x);
} while (q > 0.27597 && (q > 0.27846 || Math.Sqrt(v) > -4.0 * Math.Log(u) * Math.Sqrt(u)));
return mu + sig * v / u;
}
Leva paper描述了方程式和解决方案,但我不清楚这些值是如何确定的:
acceptance region: v^2 < -4*u^2*ln(u)
inner boundary: v = ± u*sqrt(5 - 5.136102*u)
outer boundary: v = ± u*sqrt(1.4 + 1.03696/u)
quadratic form: Q(u,v) = (u-s)^2 - b*(u-s)*(v-t) + a*(v-t)^2
s = 0.449871
t = -0.386595
r1 = 0.27597
a = 0.19600
b = 0.25472
r2 = 0.27846
v, s, t, r1, a, b, r2
的幻数来自何处?