【问题标题】:when generating normally-distributed random values, what is the most efficient way to define the range?生成正态分布的随机值时,定义范围的最有效方法是什么?
【发布时间】:2013-12-08 06:37:06
【问题描述】:

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

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. 因此 standard_deviation 将是 r/3 或在本例中为 33.333。

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

我的问题: 是否有一些我正在跳舞的公式可以在这里帮助我?我的要求如下:

  1. 必须能够准确定义数字范围。
  2. 必须在 JavaScript 中尽可能高效地完成。

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

【问题讨论】:

    标签: javascript math random gaussian normal-distribution


    【解决方案1】:

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

    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

    【讨论】:

    • @jared:这足以使近似值合理地接近实际的正态分布。请参阅此比较:en.wikipedia.org/wiki/File:Dice_sum_central_limit_theorem.svg,其中原始代码对应于n = 2
    • 谢谢!所以在这里遵循这个逻辑:jsfiddle.net/jareds/D6Nub 2,3,4,5,6,12 随机数 - 2,4,5,6 都生成相似的钟形曲线......所以其中任何一个都是相似的钟形曲线。我会继续寻找,但我认为这是我的答案。再次感谢。
    • 要获得 N(0,1),您必须使用 *2 而不是 /3,因为 that distribution 的方差是 n/12 是 n 添加的随机数的数量。然后,如果您想要一个特定的标准偏差,只需乘以它。
    • 我说*2的地方应该说Math.sqrt(2),因为6个随机数的标准差是sqrt(6/12) = sqrt(1/2)。
    • @Guffa:对于 N(0,1),我的意思是正态分布,平均值为 0,标准差为 1。我认为,你的平均值为 0,但标准差为 Math.sqrt(1/2)/3。我当然应该说* Math.sqrt(2)。我知道 OP 询问的是分布范围,而不是标准偏差,但我认为澄清这一点会很好,因为从技术上讲,法线有一个 (-inf,+inf) 范围。我会做所需的标准偏差和平均值,然后裁剪超出范围的值。
    【解决方案2】:

    我想要 0 到 1 之间的高斯随机数,在 many tests 之后(也感谢 @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));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-20
      • 2022-11-19
      • 2010-11-21
      • 2016-05-23
      • 1970-01-01
      • 2021-09-01
      • 2020-12-01
      • 1970-01-01
      相关资源
      最近更新 更多