Java Math.random()如何用于数据分布?

Java Math.random()如何用于数据分布?,java,Java,我在代码中使用Math.random()将数据分发到单独的存储桶中。 我想知道如果我在多个地方使用Math.random(),它会使用不同的数字生成器还是相同的数字生成器,因为它是一个静态方法 代码示例: public void assignVariant1() { int c1 = 0 , c2=0 , c3=0 ,c4=0; for(int i = 0 ; i < 100000 ; i++) { if(Math.random() > 0.5

我在代码中使用Math.random()将数据分发到单独的存储桶中。 我想知道如果我在多个地方使用Math.random(),它会使用不同的数字生成器还是相同的数字生成器,因为它是一个静态方法

代码示例:

public void assignVariant1() {
    int c1 = 0 , c2=0 , c3=0 ,c4=0;
    for(int i = 0 ; i < 100000 ; i++)
    {
        if(Math.random() > 0.5)
        {
            c1++;
        }else
        {
            c2++;
        }

        if(Math.random() > 0.5)
        {
            c3++;
        }else
        {
            c4++;
        }
    }
    System.out.println("c1 + c2 "+ (c1+c2));
    System.out.println("c1 + c2 "+ (c3+c4));
}
public void assignVariant1(){
int c1=0,c2=0,c3=0,c4=0;
对于(int i=0;i<100000;i++)
{
if(Math.random()>0.5)
{
c1++;
}否则
{
c2++;
}
if(Math.random()>0.5)
{
c3++;
}否则
{
c4++;
}
}
系统输出println(“c1+c2”+(c1+c2));
系统输出打印LN(“c1+c2”+(c3+c4));
}

在上面的代码中,Math.random()调用是否使用相同的伪随机数生成器?

是,使用相同的生成器。第一次调用
Math.random()
时,将创建生成器的一个实例(内部调用
new java.util.random()
),并返回一个图形。在随后的呼叫中,该实例用于生成下一个号码


一个小的点,你应该使用
=0.5
。这是因为图形包含0.0而不是1.0,0.5可以精确地表示为java
double
。您当前的方法引入了有利于
c1
c2
统计偏差,但可能不会比生成器本身更糟。

是的,使用相同的生成器。第一次调用
Math.random()
时,将创建生成器的一个实例(内部调用
new java.util.random()
),并返回一个图形。在随后的呼叫中,该实例用于生成下一个号码


一个小的点,你应该使用
=0.5
。这是因为图形包含0.0而不是1.0,0.5可以精确地表示为java
double
。您当前的方法引入了一个统计偏差
c2
,有利于
c1
,但可能不会比生成器本身更糟。

这里真正的答案是:阅读文档

对于这一点,javadoc for非常明确:

当第一次调用此方法时,它会创建一个新的伪随机数生成器,就像表达式一样

新java.util.Random()

此后,这个新的伪随机数生成器将用于此方法的所有调用,并且不会在其他任何地方使用


因此,要点是:如果您对库类有疑问,请阅读这些类附带的文档。在元水平上:努力自己“回答”这样的问题;向其他人寻求解释可能看起来像是一条捷径;但是它实际上会减慢你的速度。

这里真正的答案是:阅读文档

对于这一点,javadoc for非常明确:

当第一次调用此方法时,它会创建一个新的伪随机数生成器,就像表达式一样

新java.util.Random()

此后,这个新的伪随机数生成器将用于此方法的所有调用,并且不会在其他任何地方使用

因此,要点是:如果您对库类有疑问,请阅读这些类附带的文档。在元水平上:努力自己“回答”这样的问题;向其他人寻求解释可能看起来像是一条捷径;但它实际上会让你慢下来

它会为两个Math.random()调用使用相同的伪随机数生成器吗

它会的;但如果要使其显式,请将其作为参数传递给方法:

public void assignVariant1(Random r) {
  // ...
  if (r.nextDouble() > 0.5) {
    // ...
  }
  if (r.nextDouble() > 0.5) {
    // ...
  }
  // ...
}
这是非常明确的,每次都使用相同的
Random
实例

但真正的优势在于,它允许您通过传入一个带有已知种子的
随机
实例,重复测试该方法

它会为两个Math.random()调用使用相同的伪随机数生成器吗

它会的;但如果要使其显式,请将其作为参数传递给方法:

public void assignVariant1(Random r) {
  // ...
  if (r.nextDouble() > 0.5) {
    // ...
  }
  if (r.nextDouble() > 0.5) {
    // ...
  }
  // ...
}
这是非常明确的,每次都使用相同的
Random
实例


但真正的优势在于,它允许您通过传递一个带有已知种子的
随机
实例,重复测试该方法。

答案不错,但请在统计偏差上取消我的注释。@Bathsheba指出;但这个答案的重点不是偏差,而是控制生成的随机数序列。据我们所知,OP想要偏见。我打赌他们不会。“如果我读过的每一篇论文的结果都是一个不可靠的随机数发生器,我就有一美元,那我真的很富有了。”芭丝谢芭同意,但正如我所说,这不是答案的重点(也不是问题的重点)。确实,但我喜欢在任何时候尽可能对发生器的滥用发表评论,哪怕只是为了让我更穷。回答得好,“但请取消我关于统计偏差的说明。”芭丝谢芭说;但这个答案的重点不是偏差,而是控制生成的随机数序列。据我们所知,OP想要偏见。我打赌他们不会。“如果我读过的每一篇论文的结果都是一个不可靠的随机数发生器,我就有一美元,那我真的很富有了。”芭丝谢芭同意,但正如我所说,这不是答案的重点(也不是问题的重点)。的确,但我喜欢尽可能地对发生器的滥用发表评论,如果只是为了让我更穷。RTFM将是一个正确的答案。阅读它要比创建问题快得多。@GhostCat我读了文档,对我得到的输出感到困惑。我得到的(c1+c2)=100000和(c3+c4)的和,可能是巧合。很抱歉提出这个愚蠢的问题,但这是否意味着Math.random()将为整个应用程序范围创建一个集合?如果我用它在5个不同的地方分割数据,它会给我错误的概率?不。想想看:你循环N次。在每个循环中,增加C1或C2。最后,将C1+C2相加。你不认为结果一定是b吗