function normalDistributionRandom(min, max, mean, std_dev) {
// 参考: https://www.cnblogs.com/zztt/p/4025207.html
let realMax = max + 1;
let u = 0.0, v = 0.0, w = 0.0, c = 0.0;
do {
u = Math.random() * 2 - 1.0;
v = Math.random() * 2 - 1.0;
w = u * u + v * v;
} while (w == 0.0 || w >= 1.0);
c = Math.sqrt((-2 * Math.log(w)) / w); // Box-Muller转换
if (mean === undefined || mean === null) {
mean = (realMax + min) / 2; // 默认中间
}
if (std_dev === undefined || std_dev === null) {
std_dev = Math.min(Math.abs(realMax - mean), Math.abs(min - mean)) / 3; // 默认三个标准差
}
let rand = mean + u * c * std_dev;
if (rand >= realMax) {
return normalDistributionRandom(min, max)
}
if (rand < min) {
return normalDistributionRandom(min, max)
}
return Math.floor(rand);
}
let count = {};
let start = new Date().getTime();
for (let i = 0; i < 100000; i++) {
let it = normalDistributionRandom(40, 48, 42);
count[it + ""] = count[it + ""] || 0
count[it + ""] += 1;
}
console.log(new Date().getTime() - start + "ms", count);
测试结果,性能够用
19ms {
'40': 14000,
'41': 17423,
'42': 18901,
'43': 17892,
'44': 14750,
'45': 9717,
'46': 4955,
'47': 1823,
'48': 539
}