2011-02-01 2 views
1

Я работаю над проектом Эйлер проблема номером 205, который гласит:Вероятности на протяжении многих игр

Петр имеет девять четырехсторонний (пирамидальные) кости, каждый с лицами с номерами 1, 2, 3, 4 . Колин имеет шесть шестигранных (кубических) кости, каждая из которых с лицами, пронумерованных 1, 2, 3, 4, 5, 6.

Питер и Колин закатывают кости и сравнить итоги: самые высокие полные победы , В результате получается ничья, если итоговые значения равны.

Какова вероятность того, что Pyramidal Пит бьет кубический колин? Дайте ваш ответ округлены до семи знаков после запятой в виде 0.abcdefg

Моя первая попытка (ниже) вовлеченного имея 1000 «игры», где каждая игра была 1,000,000 по очереди. Затем возьмем среднее количество всех игр. Я постоянно получаю результаты в области .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

Как правило, это не тот случай, когда Монте-Карло является практическим решением, когда требуется такое количество знаков после запятой. Подумайте о проблеме иглы Буффона. Он сходится к pi, но очень медленно (если только вы не Марио Лаззарини). – jason

+3

Ошибка конвергенции является квадратным корнем [error ~ 1/sqrt (N)], поэтому вам, возможно, нужны контрольные точки O (10^12) –

ответ

2

Почему бы не попытаться вычислить результат комбинаторно? Явно вычислить результат путем добавления условий вида

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

Я не хочу отдавать слишком много, как другие могут захотеть сделать это –

+0

Спасибо за ваши идеи ! Это было сочетание трех лучших ответов, которые помогли мне. – Ryan

2

Хорошо, я понял. Возможно точное решение. Вот толчок.

Питер может катиться от 9 до 36.

Колин может катиться от 6 до 36.

Вычислить вероятность того, что Питер может катиться r, где r колеблется от 9 до 36.

ли то же самое для Колин, r в диапазоне от 6 до 36.

Здесь вы можете рассчитать вероятность того, что Питер победит Колина.

+0

Спасибо за толчок! Это было сочетание трех лучших ответов, которые помогли мне. – Ryan

+0

Хотелось бы узнать, почему это было отклонено. – jason

-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 кубика не девять, я стал ленивым *

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); 
} 

Пожалуйста, простите крайнюю неэффективность, но вы получите точку.

+1

«Я хотел бы сказать, что мне нравится вызов этих проблем, и я не ищу ответа, просто немного толкнул в правильном направлении». – jason

+0

Действительно, вы проголосуете меня? ... – Paul

+0

", если вы не можете решить конкретную проблему. Если вы не можете решить эту проблему, вы не сможете ее решить!" – klang

2

Сначала напишите функцию, которая вычисляет вероятность N S-сторонних кубиков, приводящих к заданному значению C.

Как только у вас есть это, напишите функцию, чтобы добавить вероятность того, что данный набор кубиков скатится меньше определенного числа.

После этого напишите функцию, которая переместится через n->(n*s) и вычисляет вероятность того, что другой набор кубиков будет меньше или равен этому.

Помните, что вероятность того, что A и B, если они не запутаны, равна P(A) * P(B).

+0

Благодарим за помощь! Это было сочетание трех лучших ответов, которые помогли мне. – Ryan

Смежные вопросы