我正在研究Project Euler问题编号205,其中指出:
彼得有九个四面(金字塔) 骰子,每个都有编号为1,2的面孔, 3,科林有六个六面(立方体) 骰子,每个都有编号为1,2的面孔, 3,4,5,6。 彼得和科林掷骰子 比较总数:总数最高 胜。结果是抽奖,如果 总数相等。金字塔形的概率是多少 皮特击败立方科林?给你的 答案四舍五入到小数点后七位 形式为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 :(得分:2)
为什么不尝试组合计算结果?通过添加表单的术语
显式计算结果a_i = P(peter throws i, Colin throws < i)
答案 1 :(得分:2)
好的,我明白了。确切的解决方案是可能的。这是一个轻推。
彼得可以9到36岁。
科林可以掷6到36个。计算彼得可以r
r
范围从9到36的概率。
为Colin做同样的事,r
从6到36不等。
从这里你可以计算出彼得击败科林的概率。
答案 2 :(得分:2)
首先,编写一个函数,计算N S面骰子的概率,得到给定值C.
一旦你有了这个,写一个函数来计算一组给定骰子滚动小于一定数量的概率。
完成后,编写一个循环遍历n->(n*s)
的函数,并计算另一组骰子小于或等于该骰子的概率。
请记住,A和B的概率(如果它们没有纠缠在一起)是P(A) * P(B)
。
答案 3 :(得分:-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);
}
请原谅极端低效率,但你明白了。