我在4个元素的小范围内使用简单的随机计算。
indexOfNext = new Random().nextInt(4); //randomize 0 to 3
当我附加调试器时,我发现前2-3次每次结果为1.
对于小范围这是错误的方法还是我应该实现另一个逻辑(检测先前的随机结果)?
注意:如果这只是巧合,那么使用这种方法是错误的方法,对吗?如果是的话,你能建议替代方法吗?可能会洗牌?理想情况下,替代方法可以检查下一个结果是否与前一个结果不同。
答案 0 :(得分:11)
每次都不要创建new Random()
,创建一个对象并多次调用它。
这是因为你需要一个随机发生器和许多数字 随机序列,而不是有许多随机发生器和得到 只是他们生成的随机序列的第一个数字。
答案 1 :(得分:9)
您通过重复创建新实例来滥用随机数生成器。 (这是由于实现设置了一个起始随机数值,它是系统时钟时间的一个非常确定的函数)。这破坏了发电机的统计特性。
您应该创建一个实例,然后根据需要调用nextInt
。
答案 2 :(得分:5)
您可以做的一件事就是抓住Random实例。它必须在每次实例化时自行播种,如果该种子相同,则每次都会生成相同的随机序列。
其他选项正在转换为SecureRandom,但您肯定希望保留该随机实例以获得最佳随机数性能。你真的只需要SecureRandom是你随机生成具有安全隐患的东西。就像实现加密算法或解决这些问题一样。
答案 3 :(得分:3)
“随机”并不意味着“非重复”,您无法通过短序列来判断随机性。例如,假设您有2个序列1和0:
101010101010101010101010101010101
和
110100100001110100100011111010001
哪个看起来更随机?第二,当然。但是当你从中获取3-4-5个数字的任何短序列时,这样的序列看起来不如从第一个序列中获取。这是众所周知的研究悖论。
答案 4 :(得分:1)
伪随机数生成器需要种子才能工作。种子是一个位数组,其大小取决于实现。 Random
的初始种子可以手动指定,也可以自动指定。
现在有几种常用的方法来分配随机种子。其中一个是++currentSeed
,另一个是当前时间戳。
java可能使用System.currentTimeMillis()
来获取时间戳并使用它初始化种子。由于时间戳的分辨率最多为毫秒(在某些机器上有所不同,WinXP AFAIK有3毫秒),在同一毫秒分辨率窗口中实例化的所有Random
个实例都将具有相同的种子。
伪随机数生成器的另一个特性是,如果它们具有相同的种子,则它们以相同的顺序返回相同的数字。
因此,如果你得到由同一种子初始化的几个Random
返回的第一个伪随机数,你必须得到相同的数字几次。而且我怀疑这就是你的情况。
答案 5 :(得分:-1)
似乎数字1有30%的机会显示其自身,这比其他数字更多。您可以阅读this链接,了解有关该主题的更多信息。
您还可以阅读Benford's law。