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

jar*_*red 3 javascript random math normal-distribution gaussian

仅供参考:随机==伪随机

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

(Math.random()-Math.random())*10+5
//generates numbers between -5 and 15
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

每一个给我一系列近似standard_deviation*(+ - 3)(假设我让程序运行时间更长).

C.我可以按如下方式计算这个范围:

  1. 假设我想要一个300-500的范围,那么var total_range = 200;
  2. 我的意思是400,我的+ - 范围是total_range/2(var r = 100)
  3. 所以standard_deviation是r/3,或者在这种情况下是33.333.

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

我的问题:我是否有一些可以帮助我的公式?我的要求如下:

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

我想也许我很接近,但它并不存在.

Guf*_*ffa 19

减去两个随机数并不能给出正态分布,它会给出在零两边线性下降的数字.请参阅此小提琴中的红色图表:

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

要获得正态分布的良好近似,请将六个随机数加在一起.请参阅小提琴中的绿色图表.

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

((Math.random() + Math.random() + Math.random() + Math.random() + Math.random() + Math.random()) - 3) / 3
Run Code Online (Sandbox Code Playgroud)

此方法基于中心极限定理,在此处作为第二种方法概述:http://en.wikipedia.org/wiki/Normal_distribution#Generating_values_from_normal_distribution

  • @jared:这个数字足以使近似值合理地接近实际正态分布.请参阅此比较:http://en.wikipedia.org/wiki/File:Dice_sum_central_limit_theorem.svg其中原始代码对应于"n = 2" (2认同)