【问题标题】:Exercise on heads or tails: Random class正面或反面练习:随机课
【发布时间】:2015-08-15 05:47:56
【问题描述】:

我制作了一个非常简单的正面或反面随机生成器。
玩 100 次时,结果总是在最大 60/40 的关系上下波动。换句话说:我从来没有得到 35 - 65 甚至 25 - 75 的结果。
我发现有点了不起的是,我相对经常得到 50/50 的结果。
这是什么原因?

这是我的主要课程(名为“play”的方法):

package headsOrTails;

public class App {

    public static void main(String[] args) { 
        HeadsOrTails headsOrTails = new HeadsOrTails(100); 
        headsOrTails.play(); 

        System.out.println(headsOrTails.getTotalHeads()); 
        System.out.println(headsOrTails.getTotalTails()); 
    } 

}

生成随机数的我的 HeadsOrTails 类:

package headsOrTails;

import java.util.Random;

public class HeadsOrTails {

    private int nrOfThrows; 
    private int totalTails; //0 
    private int totalHeads;  //1 

    //Constructor 
    public HeadsOrTails(int nrOfThrows){ 
        this.nrOfThrows = nrOfThrows; 
    } 

    public int getTotalTails(){
        return this.totalTails; 
    } 

    public int getTotalHeads(){ 
        return this.totalHeads; 
    } 

    public void play(){ 
        for (int i = 0; i < this.nrOfThrows; i++) {
            Random random = new Random(); 
            int rnd = random.nextInt(2); 

            if(rnd == 0){ 
                this.totalTails++; 
            } else { 
                this.totalHeads++; 
            }
        }

    } 
} 

【问题讨论】:

  • 你真的应该看看probability是什么。
  • 由于大多数人不是荷兰人,我认为将变量和方法名称替换为英文名称更有意义。
  • “我觉得有点不寻常的是,我相对经常得到 50/50 的结果。”请解释您的预期以及为什么您觉得这很了不起。随机数生成器的目标不是公平(如果没有另行指示)吗?除非你的意思是你对它的效果感到惊讶..
  • 看:如果你只画一次,你将获得 100% 的相同值的抽奖。这不是更了不起吗?
  • 我怀疑我的方法是否正确,但我现在看到,你玩的越多,你越有可能达到 50。对概率学了解不多,我会研究一下。跨度>

标签: java random


【解决方案1】:

试试这个:

public class Rnd {

public static void main(final String[] args) {
    int nrOfThrows = 100;
    int[] diffNr = new int[nrOfThrows];

    int plays = 1000;
    for(int i=0; i<plays; i++) {
        diffNr[play(nrOfThrows)]++;
    }
    System.out.println (Arrays.toString (diffNr));
}

static int play(final int nr) {
    int heads = 0;
    int tails = 0;
    for (int i = 0; i < nr; i++) {
        Random random = new Random ();
        int rnd = random.nextInt (2);

        if (rnd == 0) {
            heads++;
        } else {
            tails++;
        }
    }

    return Math.abs (heads-tails);
}
}

它会玩你的游戏一千次,并计算出现正面和反面之间特定差异的频率。示例输出:

[68, 0, 179, 0, 130, 0, 127, 0, 127, 0, 99, 0, 85, 0, 45, 0, 46, 0, 37, 0, 28, 0, 10, 0, 10, 0, 1, 0, 2, 0, 2, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, ... only zeros from here]

这或多或少是您所期望的。您经常看不到任何差异,然后 179/2 = 约 90 倍的差异,差异越大,可能性越小。

正如其他人已经说过的那样,看看概率以了解您为什么会这样;-)

【讨论】:

  • 有趣的测试,对我来说很新。我会更多地研究概率。谢谢。
【解决方案2】:

我认为这是因为抛硬币的概率分布。如果你减少你的 tossingloop,你会意识到分布正在远离 50/50,但是如果你将迭代增加到 10000,你可能会得到一个非常接近 50/50 的分布。检查大数定律。 它是一个数学定律,不依赖于你编写的类。

【讨论】:

    【解决方案3】:

    Random 类的行为应该是这样的。这些值应该在所有可能的结果之间平均分配。在你的情况下0和1。 您尝试的次数越少,波动越大。那么你应该减少重复。

    【讨论】:

      【解决方案4】:

      我不是随机数方面的专家,但 javadoc 指出 Random.nextInt(int) 生成一个均匀分布的整数。 因此,通过足够多的尝试,人们会期望结果接近 50/50。换句话说,使用Random.nextInt(2),您看到 0 的可能性与看到 1 的可能性一样。

      【讨论】:

        【解决方案5】:

        您总结了 100 次独立的抛硬币,每次抛硬币正面或反面的概率相同。很有可能这是 n=100 和 p=0.5 的二项分布的精确定义,描述为k ~ Binomial(100, 0.5)k 在任意指定数字对之间的概率可以精确计算到浮点限制内:

        P{40 <= k <= 60} = 0.9647997998
        P{35 <= k <= 65} = 0.9982100696
        P{30 <= k <= 70} = 0.999967840
        P{25 <= k <= 75} = 0.999999819
        

        如果您运行程序 100 次,您可能会看到少数(可能是 2、3 或 4 个)结果超出 40-60 范围的情况,并且不太可能看到超出范围的结果除非您进行更多实验,否则范围更大。在 100 次抛硬币的数千万次重复中,预计只有 25-75 范围之外的几个极端情况。

        换句话说,您似乎得到的正是数学预测的结果——很少会得到超出 40-60 范围的值,而且越来越少会得到更大的差异。

        此结果是统计假设检验的核心。如果您观察到在您处理公平硬币的假设(假设)下极为罕见的结果,那么您拒绝该假设并得出结论它不是公平硬币。总有一些机会它确实是一枚公平的硬币,并且您遇到了罕见的事件之一,但是您可以通过选择在拒绝之前结果必须有多极端的阈值来选择您愿意承受的风险。假设。

        【讨论】:

          猜你喜欢
          • 2020-09-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多