2011-02-01 92 views
1

我工作的項目歐拉問題數205規定:概率在很多遊戲

彼得有九個四面(金字塔) 骰子,每個編號爲1,2面, 3,4科林有六個六面(立方) 骰子,每個編號1 2 4 5面, 3,,,6

彼得和Colin滾動他們的骰子和 比較總計:最高總 勝。如果 總數相等,則結果爲平局。

Pyteidal Pete擊敗Cubic Colin的概率是多少?給你的答案 四捨五入到形式0.abcdefg

我最初的嘗試(下)有涉及1000「遊戲」,其中每場比賽有百萬回合7位小數 。然後取所有遊戲的平均值。我始終在.559區域獲得結果,但是當答案需要達到小數點後7位時,這並不是那麼接近。

public class pe205 { 

    public static void main(String[] args) { 

     pe205 p = new pe205(); 

     double sum = 0.0; 

     for(int i=0; i < 1000; i++){ 
      sum += p.determineProbability(); 
     } 

     System.out.println(sum/1000.0); 

    } // end main 

    public double determineProbability(){ 

     int peterWins = 0; 
     int colinWins = 0; 

     for(int i=0; i < 1000000; i++){ 

      int peterSum = 0; 
      for(int j=0; j < 4; j++){ 
       Random r = new Random(); 
       peterSum += r.nextInt(9); 
      } 

      //System.out.println(peterSum); 

      int colinSum = 0; 
      for(int j=0; j < 6; j++){ 
       Random r = new Random(); 
       colinSum += r.nextInt(6); 
      } 

      //System.out.println(colinSum); 

      if(peterSum > colinSum){ 
       peterWins++; 
      } 
      if(colinSum > peterSum){ 
       colinWins++; 
      } 

     } 
     double peteBeatsColin = (double)peterWins/(double)(colinWins + peterWins); 

     return peteBeatsColin; 

    } 

} // end class 

我讀過蒙地卡羅方法。這是否會成爲一種有用的情況,如果有的話,有人能給我一個簡短的介紹嗎?或者是我錯過了一些相當明顯的數學解決方案?

我想說,我喜歡這些問題的挑戰,我不是在尋找答案,只是朝着正確的方向前進一點點。

+0

當需要如此多的小數位數時,Monte Carlo通常不是實用的解決方案。想想布豐針的問題。它收斂到pi,但非常緩慢(除非你碰巧是Mario Lazzarini)。 – jason 2011-02-01 05:43:23

+3

錯誤收斂是平方根[error〜1/sqrt(N)],因此您可能需要O(10^12)個測試點 – 2011-02-01 05:51:20

回答

2

爲什麼不試着組合計算結果?通過添加表格的條款明確計算結果

a_i = P(peter throws i, Colin throws < i) 
+2

我不想放棄太多其他人可能想要的操作 – 2011-02-01 05:49:57

+0

感謝您的洞察!這是前三名幫助我的答案的組合。 – Ryan 2011-02-03 07:05:14

2

好吧,我想通了。確切的解決方案是可能的。這是一個微調。

彼得可以滾動9至36

科林可以滾動6至36

計算,彼得可以滾動的概率r其中r範圍爲9至36

執行相同的科林,r範圍從6到36.

從這裏你可以計算出彼得擊敗科林的概率。

+0

謝謝你的推動!這是前三名幫助我的答案的組合。 – Ryan 2011-02-03 07:06:21

-1
double colin(int n) 
{ 
    int t = 0; 
    for(int d1 = 1; d1<7; d1++) 
    for(int d2 = 1; d2<7; d2++) 
    for(int d3 = 1; d3<7; d3++) 
    for(int d4 = 1; d4<7; d4++) 
    for(int d5 = 1; d5<7; d5++) 
    for(int d6 = 1; d6<7; d6++) 
    if(d1+d2+d3+d4+d5+d6 == n) 
    t++; 
    return ((double)t)/(6*6*6*6*6*6); 
} 

- *這是如果彼得只有4個骰子不是9,我偷懶*

double peter(int n) 
{ 
    int t = 0; 
    for(int d1 = 1; d1<5; d1++) 
    for(int d2 = 1; d2<5; d2++) 
    for(int d3 = 1; d3<5; d3++) 
    for(int d4 = 1; d4<5; d4++) 
    if(d1+d2+d3+d4 == n) 
    t++; 
    return ((double)t)/(4*4*4*4); 
} 
main() 
{ 
    double r = 0.0; 
    for(int c = 4; c < 16; c++){ 
    for(int p = 6; p < 36; p++){ 
     if(c > p){ 
     r += colin(c)*peter(p); 
     } 
    } 
    } 
    System.out.println(r); 
} 

請原諒極端無效率,但你明白了吧。

2

首先,編寫一個函數,用於計算導致給定值C的N個S面骰子的概率。

一旦你有了這個,寫一個函數來加總一個給定的骰子集會滾動少於一定數量的概率。

一旦你有了,寫一個函數,循環n->(n*s)並計算出另一組骰子的概率小於或等於那個。

請記住,如果A和B沒有糾纏在一起的概率是P(A) * P(B)