每日JavaScript - 7 (随机数和数组乱序)

本文探讨了计算机生成的随机数是否真正随机的问题,详细分析了JavaScript中Math.random()生成的伪随机数特性,并通过一个数组乱序算法的实例,揭示了伪随机数的局限性和真正的随机数的获取途径。
摘要由CSDN通过智能技术生成

今天要聊一个学编程以来很感兴趣的话题:计算机的”随机“是真正的随机码?
暂时将这个大问题放下,先来解决一个问题:数组乱序
这很简单啊,例如在网上广为流传的代码

function shuffle(arr) {
	return arr.sort(function() {
		return Math.random() - 0.5;
	});
}

https://75team.com/post/array-shuffle.html
直到我看这篇文章时都认为上述算法很巧妙。作者的测试代码

var arr = [0,1,2,3,4,5,6,7,8,9];
var res = [0,0,0,0,0,0,0,0,0,0];

var t = 10000;
for(var i = 0; i < t; i++){
  var sorted = shuffle(arr.slice(0));
  sorted.forEach(function(o,i){
      res[i] += o;
  });
}

res = res.map(function(o){
    return o / t;
});

若算法是随机乱序的,则10000次测试后,每个位置出现的不同数字次数应该很接近,所以把每项的数字求和再除以10000,结果应该接近数组的平均值4.5。但可惜,结果不是4.5。我的结果是

[ 1.5845,
  1.5982,
  2.2414,
  3.0622,
  3.9838,
  4.899,
  5.7319,
  6.582,
  7.3192,
  7.9978 ]

请仔细阅读文章,文章很详细的解释为何出现这样的现象,在最后作者的数学归纳法证明经典洗牌算法能实现真正的数组乱序,简直天秀。
在JavaScript中,随机数是由Math.random()提供,但这是伪随机数。伪随机数的意思就是字面意思,不是真实不可预测的随机,而是按照一定的模拟算法产生的随机,按照这套算法产生的结果是确定的,称为伪随机。
也可以说是 伪随机性(英语:Pseudorandomness)是一个过程似乎是随机的,但实际上并不是。伪随机数是看似随机实质是固定的周期性序列,也就是有规则的随机。
随机数概念:
随机性:不存在统计学偏差,是完全杂乱的数列
不可预测性:不能从过去的数列推测出下一个出现的数
不可重现性:除非将数列本身保存下来,否则不能重现相同的数列
关于随机数的更多概念请阅读这篇文章:https://juejin.im/post/5b95004ee51d450e615fd904
总结如下:任何确定的算法都只能实现伪随机,不能实现真随机。
有限状态机不能产生真正的随机数的,所以,现代计算机中,无法通过一个纯算法来生成真正的随机数,无论是哪种语言,单纯的算法生成的数字都是伪随机数,都是由可确定的函数通过一个种子,产生的伪随机数。
所以,真随机是无法单纯由数学算法求得,必须由物理现象得到(这符合我一直以来的想法和直觉)。

延伸阅读
https://github.com/webproblem/Blog/issues/7
https://github.com/abbshr/abbshr.github.io/issues/46
题外话
后面的话题好像偏题了…未来打算学习设计模式,https://github.com/nefe/You-Dont-Need-jQuery 这个仓库或者是 30 seconds of code。学JavaScript以来很少使用jQuery这个曾经很火的库,因为ES6很多地方都学习jQuery的优点,而且前端三大框架现在太火了。但对于这个如此成熟高效的库值得每个学习前端去研究的。希望能弥补我知识的短板吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值