0

在阅读了一些帖子后,我发现Math.random()在 Java 中使用来生成整数是有偏差的。

我在这篇文章中遇到了一个算法:

使用有偏随机数生成器

它在 0 和 1 之间生成一个无偏的结果,我想将它用于我的程序。

但是,我试图在 Java 中创建一个介于 0 和某个值(例如 7)之间的无偏生成器,但我不确定该算法是否适用于一系列数字。

如果没有,我必须做什么才能创建我想要的无偏整数生成器?

4

5 回答 5

4

您需要引用声称 JavaMath.random()有偏见的参考资料,以及具体以何种方式。这将是一个巨大的问题,因为这是 Java 标准库的一个非常核心的部分。

Java 提供了更适合加密强度随机数生成的SecureRandom 。要使用它来生成 0 和 N 之间的数字,您可以使用Random.nextInt(int) 文档中提供的相同算法,但改用 SecureRandom。

不要实现你自己的随机数生成器算法,除非你愿意去麻烦证明它比股票算法更好。创建一个高质量的算法是非常困难的,而且你很可能只会让问题变得更糟。

于 2013-06-18T18:16:55.697 回答
2

我相信你误读了那些帖子。你链接的那个基本上说你不应该使用random.nextInt() % max,这确实是有偏见的;所以这种做法很幼稚。但是,如果您查看 JavasnextInt(max)函数的文档或源代码,则这更聪明。可能对你来说足够公正。只需了解有关 Java API 的更多信息,它有很多功能......

详细讨论的示例以无偏的方式生成单个位,而不是0 和 1 之间的无偏双随机!

我不相信 Java 随机生成器在您所关心的方式上存在很大偏差。但它肯定不是一个高质量的随机数,因为它需要对大多数用户来说很快。如果您想要高熵随机数,请尝试使用操作系统的高质量随机源。

无论哪种方式,如果您想要使用从您的帖子链接的方法(这可能是完全矫枉过正!)从 0 到 7 的随机数,请执行以下操作:

int bit1 = generateOneBitOfRandom();
int bit2 = generateOneBitOfRandom();
int bit3 = generateOneBitOfRandom();
int zerotoseven = (bit1 << 2) + (bit2 << 1) + bit3;

// Probably at least as good is the proper Java API:
Random random = new Random();
int zerotoseven2 = random.nextInt(8);

同样,很可能java.util.Random nextInt(8)对您来说已经足够了。除非你在做密码学。那么你真的应该考虑从 中读取一个字节/dev/random,这可能正在访问硬件熵池,如果你的 CPU 或主板具有这样的功能(只是希望没有偏见/取消偏见)。这很可能是 JavaSecureRandom所做的。再举一个例子,Java API 可能比您想象的要聪明得多。

于 2013-06-18T18:03:55.387 回答
2

您可以只使用Random.nextInt(int)。根据您的需要,使用new Random().nextInt(8). 正如文档中所说:

返回介于 0(包括)和指定值(不包括)之间的伪随机、均匀分布的 int 值

但实际上,我认为你可以一直使用Math.random()它的文档说

当这个方法第一次被调用时,它会创建一个新的伪随机数生成器,就像通过表达式一样new java.util.Random

的源代码Math.random()是:

public static double random() {
    if (randomNumberGenerator == null) initRNG();
    return randomNumberGenerator.nextDouble();
}

并且文档nextDouble还说:

返回0.0 到 1.0 之间的下一个伪随机、均匀分布的双精度值

于 2013-06-18T18:01:36.270 回答
1

尝试这个:

int randomizer(int min, int max)
{
    int n = max - min + 1;
    int remainder = RAND_MAX % n;
    int x;
    do
    {
        x = rand();
    } while (x >= RAND_MAX - remainder);
    return min + x % n;
}

它是您链接到的其他算法的修改版本。

于 2013-06-18T17:54:49.630 回答
-1

如果它只适用于 0 到 1,只需将它给你的任何值乘以 7,你就会得到一个从 0 到 7 的无偏随机数。

于 2013-06-18T17:50:28.937 回答