在开发游戏、金融模拟或科学计算应用时,我们经常需要使用正态分布(又称高斯分布)的随机数。虽然 JavaScript
原生提供了 Math.random()
生成均匀分布的随机数,但却无法直接得到正态分布的数据。
本文将介绍一种经典的转换方法 —— Box-Muller 变换(Box-Muller Transform),并通过 TypeScript
实现它,用于生成符合指定均值(mean
)和标准差(stdDev
)的正态分布随机数。
Box-Muller 变换原理简述
Box-Muller 变换是将两个 [0,1) 区间内的独立均匀分布随机数转换为符合标准正态分布(均值为 0,标准差为 1)的随机数的方法之一。
公式如下:
1 | z0 = sqrt(-2 * ln(u1)) * cos(2π * u2) |
其中:
u1
和u2
是两个独立的均匀分布随机数;z0
和z1
是独立的标准正态分布随机数。
我们这里只使用了 z0
。
TypeScript 实现
1 | function boxMullerTransform(mean: number = 0, stdDev: number = 1): number { |
这个函数支持传入 mean
和 stdDev
参数,实现自定义正态分布。
生成并分析样本数据
我们生成 10,000 个样本,并计算样本的均值和标准差,验证生成结果的正确性:
1 | const randomNumbers = Array.from({ length: 10000 }, () => boxMullerTransform(0, 1)); |
✅ 输出示例:
1 | 样本均值: -0.0168 |
可以看到样本数据的均值非常接近 0,标准差非常接近 1,表明算法效果良好。
绘制直方图(Histogram)
我们可以简单地实现一个直方图生成器,以便分析数据分布的形态:
1 | function generateHistogram(data: number[], binCount: number = 50): void { |
示例输出(部分):
1 | 直方图:[3, 3, 7, 2, 19, ..., 1, 0, 2] |
这个直方图展示了数值落在每个区间(bin)中的频数,整体呈现一个中间高两边低的“钟形曲线”,符合正态分布特征。
总结
这种生成正态分布随机数的方法非常适合用于模拟噪声、游戏角色属性分布、统计建模等场景。
附加阅读
--- 本文结束 The End ---