java.util.Random有多好?

时间:2009-01-17 15:50:40

标签: java random

两个问题:

我会为每个播种的种子获得不同的数字序列吗?

是否有一些“死”的种子? (产生零或非常快速重复的那些。)

顺便说一句,我应该使用哪些其他PRNG?

解决方案:因为,我将使用PRNG制作游戏,我不需要它在加密方面是安全的。我要和Mersenne Twister一起去,因为它的速度和时间很长。

6 个答案:

答案 0 :(得分:50)

在某种程度上,随机数生成器是课程的马匹。 Random类使用合理选择的参数实现LCG。但它仍然具有以下特点:

如果这些事情对您无关紧要,则Random具有作为JDK一部分提供的兑换功能。这对于休闲游戏(但不包括涉及金钱的游戏)来说已经足够了。这样没有弱种子。

另一个替代方法是XORShift generator,它可以用Java实现,如下所示:

public long randomLong() {
  x ^= (x << 21);
  x ^= (x >>> 35);
  x ^= (x << 4);
  return x;
}

对于一些非常便宜的操作,它的周期为2 ^ 64-1(不允许为零),并且当您重复生成值时,它很简单,可以内联。各种移位值都是可能的:有关详细信息,请参阅George Marsaglia关于XORShift发生器的论文。您可以将生成的数字中的位视为同等随机。一个主要的弱点是偶尔它会进入一个“车辙”,其中数字中没有设置很多位,然后需要几代才能摆脱这个车辙。

其他可能性是:

  • 组合不同的发生器(例如,将XORShift发生器的输出馈入LCG,然后将结果添加到具有不同参数的XORShift发生器的输出):这通常允许“平滑”不同方法的弱点,如果仔细选择组合发电机的周期,可以给出更长的时间
  • 添加“滞后”(以提供更长的时间段):基本上,生成器通常会转换生成的最后一个数字,存储“历史缓冲区”并转换,例如,第(n-1023)个。

我会说避免使用愚蠢数量的内存的生成器给你一个比实际需要更长的时间(有些时间段大于宇宙中的原子数 - 你通常不需要那个) 。请注意,“长周期”并不一定意味着“高质量发电机”(尽管2 ^ 48仍然有点低!)。

答案 1 :(得分:10)

正如zvrba所说,JavaDoc解释了正常的实现。 Wikipedia page on pseudo-random number generators有相当数量的信息,并提及Mersenne twister,这不被视为加密安全,但速度非常快,并且有各种implementations in Java。 (最后一个链接有两个实现 - 我相信还有其他实现。)

如果您需要加密安全生成,请阅读维基百科页面 - 有多种选择。

答案 2 :(得分:6)

随着RNG的发展,Sun的实施是definitely not state-of-theart,但对于大多数用途来说已经足够了。如果您需要用于加密目的的随机数,那就是java.security.SecureRandom,如果您只是想要比java.util.random更快更好的东西,那么很容易在网上找到Mersenne Twister的Java实现。

答案 3 :(得分:4)

documentation中对此进行了描述。线性同余发生器在理论上已被充分理解,并且在文献和互联网上可获得许多关于它们的材料。具有相同参数的线性同余生成器总是输出相同的周期序列,种子唯一决定的是序列开始的位置。所以你的第一个问题的答案是“是的,如果你产生足够的随机数。”

答案 4 :(得分:0)

请参阅我的博文中的答案:

http://code-o-matic.blogspot.com/2010/12/how-long-is-period-of-random-numbers.html

Random具有其状态的最大周期(长,即2 ^ 64周期)。这可以直接推广到2 ^ k - 根据需要投入尽可能多的状态位,并获得最大周期。 2Mersenne Twister实际上有一个非常 期间,相对而言(参见博客文章中的评论)。

- 糟糕。随机将自身限制为48位,而不是使用长的全64位,因此相应地,它的周期毕竟是2 ^ 48,而不是2 ^ 64。

答案 5 :(得分:-2)

如果RNG质量对您很重要,我建议您使用自己的RNG。也许java.util.Random在这个版本中非常棒,在您的操作系统上等等。它可能是。但这可能会改变。在此之前,图书馆作家在以后的版本中使事情变得更糟。

编写自己的内容非常简单,然后您确切地知道发生了什么。升级等不会改变。这里有一个generator你可以在10分钟内移植到Java。如果你从现在起一周内开始用一种新语言写作,你可以再次移植它。

如果您没有实现自己的RNG,可以从信誉良好的来源获取知名RNG的代码,并在项目中使用它。那么没人会把你的发电机从你身下改变。

(我并不主张人们提出他们自己的算法,只有他们自己的实现。大多数人,包括我自己,都没有开发他们自己的算法的业务编写一个你认为很棒的糟糕生成器很容易。这就是为什么人们需要问这样的问题,想知道库生成器有多好。我引用的生成器中的算法已经通过了很多同行评审。 )