JAVA随机数真的随机吗?

随机数

java的随机数真的非常易于使用。它可以让你模拟准确的统计样本、实现加密算法,最重要的是,你可以不假思索地使用。在Java中,访问随机数的常用方法是通过一个名为 java.util.Random的类。您可以使用一个种子数或当前时间来实例化它,然后您就有了一系列的值,你可以很轻易的访问这些值,方法如下:

Random random = new Random();
// Prints out either 0 or 1
System.out.println(random.nextInt(2));

用户参与时间

如果您的期望没有因以下问题而产生偏差:您可以打印以下代码:

public static void main(String[] args) {
       int start = 0;
       int end = 1000;
       int countOnes = 0;
       for (int i = start; i < end; i++) {
             countOnes += new Random(i).nextInt(2);
            }
       System.out.println(countOnes);
}

如果我们运行该程序,我们会得到一下结果:

 1000

这太令人惊讶了——如果你问我预期的数字是多少,我会告诉你,我不能给你一个确切的数字,但我预计大约是500。这是基于这样一个假设,以为随机数的概率吩咐符合均匀分布,因此结果为1和0的概率都是50%。它不会精确地计算出500,但如果样本量为1000,那么总数将接近500。如果我们将终点值更改为4000,则会得到:

4000

再次调用nextInt(2)应该返回一个介于0和1之间的随机数,但它只返回1。我们设置,起点为4000,终点为5000,结果又会怎么样呢?

96

好的,我现在有更多的零,但比我预期的要少很多。

为什么会这样?

人们通常将基于计算机的随机数生成器称为伪随机数生成器,但它很少描述伪随机的实际含义。在这种情况下,我们真正的意思是,我们有一个算法,这个算法产生一个确定性的数字序列,这个序列是由一个种子数初始化的。这个序列看起来很随机,但它只是表面现象。上面的小程序所做的只是从序列中抽取第一个随机数。

这是一个简单的算法,但它确实引发了一些有趣的问题,java.util.Random使用线性同余生成器生成其数字,其优点是简单快速。不幸的是,这样做的代价是它不是很随机的——即使程序员正确地使用它。它也根本不适合蒙特卡罗模拟或晶体算法。

这也不是Java特有的问题python的早期版本使用了Wichmann&Hill 1982年的算法。这会受到短期影响,这意味着数字在一段时间后开始重复。最近的版本使用Mersenne Twister作为其算法,该算法具有更好的特性,但仍然不适合用于加密。

总结

在所有这些情况下需要记住的是,伪随机数不是随机数,如果您关心统计随机性,那么您需要在算法选择和实现使用方面都加以注意。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇