2个randoms似乎给出了几乎相同的结果

时间:2014-03-06 10:18:17

标签: java android random probability

提前感谢您抽出时间来查看我的问题。任何有相同问题的人都希望我们能找到解决方案......

所以基本上我有一个应用程序同时旋转2个硬币并显示结果。

此方法生成第一枚硬币......

    public void coinResult1(){
     ImageView coin1View = (ImageView) findViewById(R.id.coin1);
     Random r = new Random();
     int coin1result = r.nextInt(2);

     if (coin1result == 0){
        coin1View.setBackgroundResource(R.drawable.coinheads);
        coinresult1 = 0;
     }
        else if (coin1result == 1) {
            coin1View.setBackgroundResource(R.drawable.cointails);
            coinresult1 = 1;
        }
}

这是第二枚硬币

public void coinResult2(){
    ImageView coin2View = (ImageView) findViewById(R.id.coin2);

    Random r = new Random();
    int coin2result = r.nextInt(2);

    if (coin2result == 0){
        coin2View.setBackgroundResource(R.drawable.coinheads);
        coinresult2 = 0;
    }
        else if (coin2result == 1) {
            coin2View.setBackgroundResource(R.drawable.cointails);
            coinresult2 = 1;
        }
}

这与按钮的onclick()相关联,该按钮将结果检查给玩家选择

public void checkResult(){
        coinResult1();
        coinResult2();
        coinResult = coinresult1 + coinresult2;
        if (coinResult == playerSelection){
            playerWins();
            buttonsReset();
        }
        else {
            playerLost();
            buttonsReset();
        }
    }

现在唯一的问题是...... 这1000个印刷机的两个硬币的结果是...... HeadsHeads 54%

HeadsT​​ails 2%

TailsTails 44%

1000000次旋转的

大致相同的百分比

每个硬币结果单独计算时

COIN1头部53%尾部47%

COIN2头部48%尾部52%

现在我的朋友说他们的赔率有些不对了......因为HeadsT​​ails不是很高的百分比,他预计每个组合随机接近33%

代码似乎更喜欢HeadsHeads和TailsTails或HeadsT​​ails .....我已多次尝试并持续获得HeadsT​​ails的低百分比

任何人都可以了解最新情况......是什么导致HeadsT​​ails很少出现?

希望尽快收到回复

3 个答案:

答案 0 :(得分:5)

重复实例化Random会破坏生成器的统计属性。

您需要创建一个实例并将其传递给您的函数。更好的是,在班上使用一个字段。

请关注Random班级Is Random class thread safe?的线程安全问题,请参阅此问题。这似乎表明您应该synchronize nextInt来电。

答案 1 :(得分:1)

永远不会一遍又一遍地重新创建随机数生成器:

  public void coinResult1(){
    ImageView coin1View = (ImageView) findViewById(R.id.coin1);
    Random r = new Random(); // <- That's the source of errors!
    int coin1result = r.nextInt(2);
    ...

相反,一劳永逸地创建随机生成器实例

  // Simplest, not thread-safe amendment
  private static Random s_Gen = new Random();
  ...

  public void coinResult1(){
    ImageView coin1View = (ImageView) findViewById(R.id.coin1);

    int coin1result = s_Gen.nextInt(2);
    ...

不良行为的原因是,当您重新创建Random时,它经常从相同的种子(通常是当前时间)重新初始化,因此生成相同的值

答案 2 :(得分:0)

您必须只创建一个Random实例。

    private Random r;

    // initialize r in onCreate or somehere else only once 

protected void onCreate(Bundle savedInstanceState){
            // ...
    r = new Random();
}

public void coinResult1(){
     ImageView coin1View = (ImageView) findViewById(R.id.coin1);
     int coin1result = r.nextInt(2);

     if (coin1result == 0){
        coin1View.setBackgroundResource(R.drawable.coinheads);
        coinresult1 = 0;
     }
        else if (coin1result == 1) {
            coin1View.setBackgroundResource(R.drawable.cointails);
            coinresult1 = 1;
        }
}

public void coinResult2(){
    ImageView coin2View = (ImageView) findViewById(R.id.coin2);
    int coin2result = r.nextInt(2);

    if (coin2result == 0){
        coin2View.setBackgroundResource(R.drawable.coinheads);
        coinresult2 = 0;
    }
        else if (coin2result == 1) {
            coin2View.setBackgroundResource(R.drawable.cointails);
            coinresult2 = 1;
        }
}