2016-07-28 19 views
-1

数学的な出力とプログラムが与えるものとの違いを考慮して問題が発生しました。確率計算のJava出力

1/6確率で同じ数字を2回得る確率を計算したいと思います。これは1 in 1/6 * 1/6 = 36です。しかし、私は42-43の1の間の答えを得る。なにが問題ですか?

int guess = (int) (Math.random() * 6); 
int real = (int) (Math.random() * 6); 
int countTot = 0; 
int countReal = 0; 
int countGen = 0; 

while (true) { 
    if (countReal == 2) { 
     countGen++; 
     countReal = 0; 
     if (countGen == 1000000) { 
      System.out.println("Probability: 1 in " + countTot/countGen); 
      System.exit(0); 
     } 
    } 
    if (guess == real) { 
     countReal++; 
     countTot++; 
    } else { 
     countReal = 0; 
     countTot++; 
    } 
    guess = (int) (Math.random() * 6); 
    real = (int) (Math.random() * 6); 
} 

は、私はこの1000000回(countGen)を行い、結果の平均を取ることを考えてみましょう。前もって感謝します。次のコードを実行

答えて

3

int n = 1_000_000; 
int count = 0; 
Random rnd = new Random(); 

for (int i = 0; i < n; i++) { 
    int a = rnd.nextInt(6); 
    int b = rnd.nextInt(6); 
    int c = rnd.nextInt(6); 
    int d = rnd.nextInt(6); 

    if (a == b && c == d) { 
     count++; 
    } 
} 

System.out.println(count + "/" + n); 
System.out.println("Or about 1 in " + (n * 1.0/count)); 

だから35.8512888538343

1000000分の27893
または約1を与え、なぜあなたは42で1を得るのですか?

2つの数字を同じにすると、countRealが増えます。 2回目の数字が同じになった場合は、もう一度countRealをインクリメントしてから、ゼロにリセットします。 もう一度の2つの数字を取得した場合は、すでにランカウントを中止しています。このはおそらくの確率に影響します。

int n = 1_000_000; 
int count = 0; 
Random rnd = new Random(); 

boolean matched_last_time = false; 
for (int i = 0; i < n; i++) { 
    int a = rnd.nextInt(6); 
    int b = rnd.nextInt(6); 
    boolean match = a == b; 

    if (match && matched_last_time) { 
     count++; 
     // match = false; // Uncomment this line, & probability changes to 1 in 42 
    } 
    matched_last_time = match; 
} 

System.out.println(count + "/" + n); 
System.out.println("Or about 1 in " + (n * 1.0/count)); 
+1

このアルゴリズムは、OPよりはるかに明確です。 –

+0

助けてくれてありがとう、私は今理解している! – Playdowin

1

あなたはそれが間違ってカウントされています


は、別の方法を示しますスロー回数(countTot)と成功した成功回数()を比較しています()。あなたはそれを1/72にする必要があります。しかし、あなたはそれを得ていません、なぜなら、最初のペアが一致していなければ早期に終了するからです。

以下のコードは正解です。それは本当に素敵ではないですが、私は物事のほとんどの名前を変更するだろうが、私は可能な

int guess = (int) (Math.random() * 6); 
    int real = (int) (Math.random() * 6); 
    int countTot = 0; 
    int countReal = 0; 
    int countGen = 0; 

    while (true) { 
     if (countReal == 2) { 
      countGen++; 
      countReal = 0; 
      if (countGen == 1000000) { 
       System.out.println("Probability: 1 in " + (countTot/2)/countGen); 
       System.exit(0); 
      } 
     } 
     if (guess == real) { 
      countReal++; 
      countTot++; 
     } else { 
      countTot++; 
      if (countReal == 0) { 
       countTot++; 
      } 
      countReal = 0; 
     } 
     guess = (int) (Math.random() * 6); 
     real = (int) (Math.random() * 6); 
    } 
+0

助けてくれてありがとう、私は今理解する! – Playdowin

2

あなたは重複を許可せずに連続したマッチングのペアの数をカウントしているとして、オリジナルと同様に、それを維持したいです。すべてが等しい3つの乱数のシーケンスを取得した場合は、2つのペアをカウントする必要がありますが、1つしかカウントしません。オーバーラップが許されないということは、1対がその前に来たものに依存することを意味する。確率を増やすには、イベントが独立していることを保証する必要があります。