随机类表演奇数?

时间:2012-11-05 23:14:52

标签: java random

在此代码中:

Random random = new Random(441287210);
for(int i=0;i<10;i++)
    System.out.print(random.nextInt(10)+" ");
}

每次输出都是1 1 1 1 1 1 1 1 1 1

这是为什么? Isn&#t; t Random应该......好吧......随机?我认为Random类使用System.nanoTime,因此输出通常应该是随机的。有人可以解释一下吗?

6 个答案:

答案 0 :(得分:18)

让它打印更多,前100个是

1 1 1 1 1 1 1 1 1 1 3 4 7 2 2 6 0 3 0 2 8 4 1 6 0 0 0 2 8 2 9 8 9 2 5 2 1 1 4 5 3 4 1 4 1
8 7 6 6 0 6 5 0 4 5 5 6 0 8 3 8 9 7 4 0 9 9 7 7 9 3 9 6 4 5 0 6 3 7 4 9 8 7 6 2 8 9 8 4 4
8 4 9 0 1 6 9 6 1 5

看起来没问题。

每个好的(伪)随机序列都包含重复数字的条纹,这个条纹从一个开始。

答案 1 :(得分:12)

Random类生成的值为伪随机:它们是使用基于种子值的确定性算法创建的。通常(例如,如果使用无参数构造函数),使用当前时间初始化种子,这显然是唯一值。因此,生成了一个独特的“随机”序列。

这里使用的是一个常量种子值,它不会在代码执行之间发生变化。因此,您总是得到相同的序列。恰好这个特定种子的序列为1 1 1 1 1 1 ...

答案 2 :(得分:4)

没有什么可说的,连续10个1的序列是不可能的。谁给了你种子值441287210恰好发现了这样一个值,导致连续10 1 s开始。如果您继续拨打nextInt()(即超过10次),您会看到随机值。应该可以找到导致其他“明显非随机”序列的其他种子值。

答案 3 :(得分:3)

随机是linear congruential generator;即它基于以下形式的公式:

N <- (N * C1 + C2) % M

其中C1,C2和M是常数。

这类发生器的一个特性是具有高自相关性。实际上,如果您绘制连续数字,您可以在数字中看到清晰的剥离模式。

你的测试程序已经从基础生成器中有效地获取了10个连续数字,计算出它们的模数为10 ...并且发现它们都是相同的。实际上,模10在短时间内与发电机的自然周期“共振”。

这是使用具有高自相关性的PRNG的缺点之一。通俗地说......它“不是很随机”......如果你在随机性至关重要的情况下使用它,你就会遇到麻烦。


注意:

  • Random不是随机数生成器。它是伪随机数字生成器。这意味着如果您知道初始状态,则生成的数字完全可以预测。
  • 为Random使用真正的随机种子并没有多大帮助。它只会使问题难以重现。
  • Random可能有其他种子会给你类似的测试模式。
  • 从纯粹的数学角度来看,十个一个或多或少不是“随机”的,而不是十个数字的任何其他序列。但从数学的角度来看,Random根本不是随机的。事实上,一旦你弄清楚N的当前值是什么,它就完全可以预测了。问题是自相关使得序列看起来非直观。
  • 如果你想避免这种直观的非随机性,可以使用SecureRandom,它应该是一个真正的随机数源,或者是一个非常难以预测的伪随机数生成器。

答案 4 :(得分:1)

如果使用for(int i=0;i<100;i++),则输出的序列再次“更随机”。连续发生10个1的随机序列的概率可能很小,但并非不可能。 (只要给出足够的样本,几乎肯定会发生任何序列。)

这只是一个有趣的巧合。

答案 5 :(得分:0)

随机类使用种子在调用nextInt()时生成随机数,并建议为长数,当您创建随机对象时,您提供的int不够随机性。

尝试运行循环20次,您将看到随机性或移除种子或提供非常长的种子值