使用Math.random()生成均匀分布

Generating uniform distribution using Math.random()

本文关键字:分布 Math random 使用      更新时间:2023-09-26

在MDN Math.random网页中,示例函数getRandomInt(..)的注释表示没有使用Math.round(),因为它给出了非均匀分布,这意味着使用Math.floor(..)将产生均匀分布

// Returns a random integer between min (included) and max (excluded)
// Using Math.round() will give you a non-uniform distribution!
function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

然而,下面的代码表明,生成随机数的频率与该数的值成正比。即数值越高,频率越高。这种行为在nodejs和firefox浏览器上是相同的。

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

// Returns a random integer between min (included) and max (excluded)
// Using Math.round() will give you a non-uniform distribution!
function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}
var data = {};
var a;
var i = 0;
for (i = 0; i < 100000; ++i) {
  a = getRandomInt(1, 50);
  if (typeof data[a] === 'undefined') { // first time initialize
    data[a] = a;
  } else {
    data[a] = data[a] + a;
  }
}
//console.log(data);
document.getElementById("json").innerHTML = JSON.stringify(data, undefined, 2);
<pre id="json"></pre>

因此,使用Math.random()的这个属性,如何生成均匀分布。

使用a递增计数器。计数器的结果将是a*<actual frequency>

如果你用1递增,你会发现它实际上是均匀分布的。

if (typeof data[a] === 'undefined') { // first time initialize
    data[a] = 1;
} else {
    data[a] = data[a] + 1;
}

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

// Returns a random integer between min (included) and max (excluded)
// Using Math.round() will give you a non-uniform distribution!
function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}
var data = {};
var a;
var i = 0;
for (i = 0; i < 100000; ++i)
{
    a = getRandomInt(1,50);
    if (typeof data[a] === 'undefined') { // first time initialize
    data[a] = 1;
    } else {
    data[a] = data[a] + 1;
    }
}
//console.log(data);
document.getElementById("json").innerHTML = JSON.stringify(data, undefined, 2);
<pre id="json"></pre>