1

使用 Math.random 来生成随机数在日常操作中是普遍并且是简单的。如下:

let rnd = Math.random() * 10; 

上述代码的作用是生成 0~10 的随机数。

那么,这些随机数是出现的概率是均衡的吗?
笔者没办法直接回答这个问题。因为生成的随机数个数理论上是一个无穷大的数集,不过,可以按数值大小范围来估算数值的分布是否平均:

let bucket = new Array(10).fill(0); 
let res = new Array(500000); 
// 做50万次随机数
for(let i = 0; i < 500000; ++i) {
    res[i] = Math.random() * 10; 
    // 数值大小规类
    let num = res[i]; 
    for(let i = 0; i < 10; ++i) {
        if(num >= i * .1 && num < (i + 1) * .1) {
            ++bucket[i]; 
        }
    }
}

bucket.forEach(
    (count, index) => {
        console.log(index * .1 + "~" + (index + 1) * .1 + "的概率:" + count / 500000)
    }
)

以下是一次输出结果:

  • 0~0.1的概率:0.010244
  • 0.1~0.2的概率:0.009868
  • 0.2~0.3的概率:0.009744
  • 0.3~0.4的概率:0.010024
  • 0.4~0.5的概率:0.009818
  • 0.5~0.6的概率:0.009814
  • 0.6~0.7的概率:0.010048
  • 0.7~0.8的概率:0.009834
  • 0.8~0.9的概率:0.010154
  • 0.9~1的概率:0.009988

结果显示 Math.random() * 10 生成的数值分布是比较均衡的。

但是,如果把「随机数」改成「随机整数」。代码改成:

let rnd = Math.round(Math.random() * 10); 

上面代码是生成 0~10 的随机整数。

那么,这些随机整数是出现的概率是均衡的吗?

笔者直观上觉得是随机的,但是实际情况并不是!测试代码如下:

let res = new Array(11).fill(0); 
// 做一万次随机数
for(let i = 0; i < 500000; ++i) {
    ++res[Math.round(Math.random() * 10)]; 
}

res.forEach((count, index) => console.log(index + "的概率:" + count / 500000))

以下是一次结果:

  • 0的概率:0.050028
  • 1的概率:0.09957
  • 2的概率:0.100616
  • 3的概率:0.099684
  • 4的概率:0.100672
  • 5的概率:0.099588
  • 6的概率:0.100446
  • 7的概率:0.100276
  • 8的概率:0.099664
  • 9的概率:0.099628
  • 10的概率:0.049828

不难发现,010 的概率是其它数值的一半左右,而其它数值的概率相差无几。

Math.round 方法是造成「随机整数」不均衡的原因

Math.round/Math.ceil/Math.floor 这三个函数作用是使一定范围内的实数转换成同一个整数。以 Math.round 为例如下:

Math.round

从上图可以直观地看到,头尾两数(0&10)的取值范围是其它整数的一半!

生成随机均衡整数的一种方案
其实,只需要保证取值范围的长度一致即可以实现随机均衡整数。以下是笔者实现的一种方案:

let res = new Array(11).fill(0); 
// 做一万次随机数
for(let i = 0; i < 500000; ++i) {
    ++res[Math.floor(Math.random() * 11)]; 
}

res.forEach((count, index) => console.log(index + "的概率:" + count / 500000))

以下是一次输出结果:

  • 0的概率:0.090828
  • 1的概率:0.090988
  • 2的概率:0.09048
  • 3的概率:0.08958
  • 4的概率:0.091516
  • 5的概率:0.090826
  • 6的概率:0.09112
  • 7的概率:0.091668
  • 8的概率:0.090918
  • 9的概率:0.090626
  • 10的概率:0.09145

从结果上看分布是均衡的。


leeenx
614 声望8 粉丝

JD.COM & 凹凸实验室