我正在使用java 6 random(java.util.Random,linux 64)来随机决定将一个版本的页面服务到第二个版本(正常的A / B测试),从技术上讲,我将该类初始化一次默认的空构造函数,它作为属性注入bean(Spring)。 大多数情况下,页面的副本在彼此的8%(+ - )之内,但有时我会看到偏差高达20%,例如:
我现在有两个分裂的副本:680/570是否正常? 是否有比java随机更好/更快的版本?
谢谢
答案 0 :(得分:3)
20%的偏差看起来确实相当大,但您需要与经过培训的统计人员交谈,以确定它是否具有统计上的异常性。
更新 - 答案是它不一定是异常的。统计数据预测,大约0.3%的时间会得到这样的异常值。
这样的结果肯定是由随机数发生器引起的。 Random
类使用简单的“线性同余”算法,这类算法强烈地自相关。根据您使用随机数的方式,这可能会导致应用程序级别的异常。
如果这是您的问题的原因,那么您可以尝试用加密强度随机数生成器替换它。请参阅SecureRandom
的javadoc。 SecureRandom
比Random
贵,但这不太可能会对您的用例产生任何影响。
另一方面,如果这些异常值实际上大致以理论预测的速率发生,那么改变随机数发生器应该没有任何区别。
如果这些异常值真的很麻烦,那么你需要采取不同的方法。而不是生成N个随机选择,生成一个具有所需比率的false / true列表,然后随机播放列表;例如使用Collections.shuffle
。
答案 1 :(得分:0)
我认为这是相当正常的,因为它意味着生成随机序列。如果你想在一定的时间间隔后重复模式,我想你可能想在构造函数中使用一个特定的seed
值,并在一定的时间间隔后用相同的种子重置随机。
e.g。在每次调用{/ 1}}的100/500 / n之后,使用Random.next..
方法重置具有旧值的种子。
答案 2 :(得分:0)
java.util.Random.nextBoolean()是一种标准二项分布的方法,其标准差为sqrt(n * p *(1-p)),p = 0.5。
因此,如果您进行900次迭代,则标准偏差为sqrt(900 * .5 * .5)= 15,因此大多数情况下分布将在435 - 465范围内。
然而,它是伪随机的,并且在重新开始之前它将经历有限的数字循环。因此,如果您有足够的迭代次数,实际偏差将远小于理论偏差。 Java使用公式seed =(seed * 0x5DEECE66DL + 0xBL)&amp; ((1L <&lt;&lt; 48)-1)。您可以使用较小的数字编写不同的公式,以便有目的地获得较小的偏差,这将使其成为更糟糕的随机数生成器,但更适合您的目的。
例如,您可以创建一个包含5个trues和5个falses的列表,并使用Collections.shuffle随机化列表。然后按顺序迭代它们。在10次迭代之后,您重新洗牌并从头开始。这样你就不会偏离超过5个。
请参阅http://en.wikipedia.org/wiki/Linear_congruential_generator了解数学。