无偏随机整数生成器

时间:2013-06-18 17:48:53

标签: java random

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

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

Unbiased random number generator using a biased one

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

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

如果没有,为了创建一个我想要的无偏整数生成器,我该怎么做?

5 个答案:

答案 0 :(得分:4)

您需要引用声称Java Math.random()有偏见的引用,以及确切的方式。这将是一个巨大的问题,因为这是Java标准库的核心部分。

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

不要实施自己的随机数生成器算法,除非您愿意去解决问题以证明它比库存更好。创建一个高质量的算法非常困难,你很可能只会让问题变得更糟。

答案 1 :(得分:2)

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

  

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

但实际上,我认为你可以一直使用Math.random()Its documentation says

  

首次调用此方法时,它会创建一个新的伪随机数生成器,就像表达式new java.util.Random

一样

Math.random()的源代码是:

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

nextDouble的{​​{3}}也说:

  

返回下一个伪随机数,均匀分布在0.0和1.0之间的双重值

答案 2 :(得分:2)

我相信你误读了那些帖子。你链接的那个人基本上说你不应该使用random.nextInt() % max ,这确实是有偏见的;所以这种方法非常幼稚。但是,如果你看一下Javas nextInt(max)函数的文档或源代码,那么 比那更聪明。可能无偏见给你。只需了解Java API的更多信息,它就有很多功能......

详细讨论的示例以无偏的方式生成单个位 0到1之间的无偏双重随机!

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

无论哪种方式,如果你想要一个从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或主板有这样的功能(只希望一个没有偏置/偏置取消),它可能正在访问硬件熵池。这最有可能是Javas SecureRandom所做的。再一个例子,Java API可能比你想象的更聪明

答案 3 :(得分: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;
}

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

答案 4 :(得分:-1)

如果只能从0到1工作,只需将它给你的任意乘以7,你就会得到一个0到7的无偏随机数。