Java Math.random()如何用于数据分布?
我在代码中使用Math.random()将数据分发到单独的存储桶中。 我想知道如果我在多个地方使用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
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可以精确地表示为javadouble
。您当前的方法引入了有利于c1
的c2
统计偏差,但可能不会比生成器本身更糟。是的,使用相同的生成器。第一次调用Math.random()
时,将创建生成器的一个实例(内部调用new java.util.random()
),并返回一个图形。在随后的呼叫中,该实例用于生成下一个号码
一个小的点,你应该使用
=0.5
。这是因为图形包含0.0而不是1.0,0.5可以精确地表示为javadouble
。您当前的方法引入了一个统计偏差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吗