当生成正态分布的随机值时,定义范围的最有效方法是什么

when generating normally-distributed random values, what is the most efficient way to define the range?

本文关键字:定义 范围 有效 是什么 方法 正态分布 随机      更新时间:2023-09-26

FYI:random==伪随机

A。当生成均匀随机数时,我可以指定一个范围,即:

(Math.random()-Math.random())*10+5
//generates numbers between -5 and 15

B。生成一组具有高斯型正态随机性的随机值:

//pass in the mean and standard deviation
function randomNorm(mean, stdev) {
  return Math.round((Math.random()*2-1)+(Math.random()*2-1)+(Math.random()*2-1))*stdev+mean);
}
//using the following values:
{
  mean:400, 
  standard_deviation:1
  //results in a range of 397-403, or +-range of 3
},
{
  mean:400, 
  standard_deviation:10
  //results in a range of 372-429, or +-range of 30
},
{
  mean:400, 
  standard_deviation:25
  //results in a range of 326-471, or +-range of 75
}

每一个都给了我一个大约标准偏差*(+-3)的范围(假设我让程序运行得更长)。

C。我可以如下计算这个范围:

  1. 假设我想要300-500的范围,那么var total_range=200
  2. 我的平均值是400,我的+-范围是total_range/2(var r=100)
  3. 因此标准偏差将是r/3,或者在这种情况下是33.333

这似乎奏效了,但我不知道我在数学方面做什么,所以我觉得自己像个白痴,这个解决方案感觉很笨拙,也不完全准确。

我的问题:有什么公式可以帮助我吗?我的要求如下:

  1. 必须能够准确地定义一系列数字
  2. 必须在JavaScript中尽可能高效地完成

我想也许我已经很接近了,但还不完全。

减去两个随机数不会得到正态分布,它会得到在零两侧线性下降的数字。请参阅此小提琴中的红色图表:

http://jsfiddle.net/Guffa/tvt5K/

为了得到正态分布的一个很好的近似值,把六个随机数加在一起。请参阅小提琴中的绿色图表。

因此,要获得正态分布的随机数,请使用:

((Math.random() + Math.random() + Math.random() + Math.random() + Math.random() + Math.random()) - 3) / 3

该方法基于中心极限定理,这里概括为第二种方法:http://en.wikipedia.org/wiki/Normal_distribution#Generating_values_from_normal_distribution

我想要0到1之间的高斯随机数,经过多次测试(也感谢@Guffa的回答),我发现这是最好的:

function gaussianRand() {
  var rand = 0;
  for (var i = 0; i < 6; i += 1) {
    rand += Math.random();
  }
  return rand / 6;
}

作为奖励:

function gaussianRandom(start, end) {
  return Math.floor(start + gaussianRand() * (end - start + 1));
}