【问题标题】:2 randoms seem to give near identical result2个随机数似乎给出了几乎相同的结果
【发布时间】:2014-04-08 21:47:50
【问题描述】:

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

所以基本上我有一个应用程序可以同时旋转 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%

头尾 2%

TailsTails 44%

1000000 次旋转的百分比大致相同

当每个硬币结果单独计算时

COIN1 正面 53% 反面 47%

COIN2 正面 48% 反面 52%

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

代码似乎有利于 HeadsHeads 和 TailsTails 或 HeadsT​​ails .....我尝试了几次,但一直得到低百分比的 HeadsT​​ails

任何人都可以对正在发生的事情有所了解......以及导致 HeadsT​​ails 很少出现的原因是什么?

希望尽快回复

【问题讨论】:

  • Random 的实例默认使用系统时间播种。如果恰好在一毫秒内创建了两个实例,它们将有效地生成相同的伪随机数。

标签: java android random probability


【解决方案1】:

您对Random 的重复实例化正在破坏生成器的统计属性。

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

有关Random 类的线程安全问题,请参阅此问题:Is Random class thread safe?。似乎建议您应该 synchronize 拨打 nextInt 电话。

【讨论】:

  • 抱歉,您指的是哪些线程问题?根据stackoverflow.com/questions/5819638/is-random-class-thread-safe Random 类是线程安全的...
  • @GermannArlington:太好了。我是一只偏执的老猫。你介意我把这个纳入我的回答吗?
  • 感谢您的回答,他们都很棒...生病 changeCode 看看会发生什么
【解决方案2】:

你应该永远不要一遍又一遍地重新创建随机数生成器:

  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 时,它通常会从 相同的种子(通常是当前时间)重新初始化,因此会生成 相同的值 em>。

【讨论】:

    【解决方案3】:

    您只能创建一个 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;
            }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-08-31
      • 2019-08-04
      • 2012-05-16
      • 2022-08-13
      • 2014-06-28
      • 1970-01-01
      • 2021-12-10
      • 2015-08-25
      • 1970-01-01
      相关资源
      最近更新 更多