任务:不公平的骰子(6 面)被滚动 n 次。1 的概率是 p1,2 的概率是 p2,依此类推。编写一个计算机程序,对于给定的 n (n<100),集合 (p1,p2,p3,p4,p5,p6) 和 $x \in [n,600n]$ 的概率将找到总和的概率骰子值小于 x。程序不能运行超过 5 分钟。这是一个额外的问题,会给我加分,但到目前为止没有人这样做。我怀疑像我这样的初学者计算机科学家也可以从这段代码中学习,因为我在网上找到了 0 帮助关于偏向骰子的帮助,并想出了类似轮盘赌的解决方案。我也有点想向世界展示我的方式。
我有 2 个解决方案 - 使用几何概率和统计概率。
我的问题是:1)我这样做是正确的还是我在某个地方出错了?2)你认为哪一个给我更好的答案几何或统计概率?我的直觉说它是几何的,因为它更可靠。我认为我的代码给我的答案是正确的——通常超过 0.99 ..... 我希望有人检查我的工作,因为我完全不确定,我想与其他人分享这段代码。
我更喜欢 Java,因为它比带有循环的 R 快得多,但我也为统计提供了 R 代码,它们非常相似,我希望这不是问题。
Java代码:
import java.util.ArrayList;
public class Statistical_prob_lisayl2_geometrical {
public static double mean(ArrayList<Double> a) {
double sum=0;
int len = a.size();
for (int i = 0; i < len; i++) {
sum = sum + a.get(i);
}
return (sum/len);
}
public static double geom_prob(double p1,double p2,double p3,double p4,double p5,double p6){
ArrayList<Double> prob_values = new ArrayList<Double>();
int repeatcount = 1000000;
int[] options = {1,2,3,4,5,6};
int n = 50;
double[] probabilities = {p1,p2,p3,p4,p5,p6};
for (int i = 0 ; i < repeatcount ; i++ ) { // a lot of repeats for better statistical probability
int sum = 0; //for each repeat, the sum is being computed
for (int j = 0; j < n ; j++ ) { // for each repeat there is n cast of dies and we compute them here
double probability_value=0; // the value we start looking from with probability
double instant_probability = Math.random(); // we generate random probability for dice value
for (int k = 0; k < 6; k++ ) { // because we have 6 sides, we start looking at each probability like a roulette table
probability_value = probability_value + probabilities[k]; // we sum the probabilities for checking in which section the probability belongs to
if (probability_value>instant_probability) {
sum = sum + options[k]; // if probability belongs to certain area , lets say p3 to p4, then p3 is added to sum
break; // we break the loop , because it would give us false values otherwise
}
}
}
double length1 = (600*n)-n-(sum-n); //length of possible x values minus length of sum
double length2 = 600*n-n;
prob_values.add( (length1/length2) ); // geometric probability l1/l2
}
return mean(prob_values); // we give the mean value of a arraylist, with 1000000 numbers in it
}
public static double stat_prob(double p1,double p2,double p3,double p4,double p5,double p6){
ArrayList<Double> prob_values = new ArrayList<Double>();
int repeatcount = 1000000;
int[] options = {1,2,3,4,5,6};
int n = 50;
double[] probabilities = {p1,p2,p3,p4,p5,p6};
int count = 0;
for (int i = 0 ; i < repeatcount ; i++ ) {
int sum = 0;
for (int j = 0; j < n ; j++ ) {
double probability_value=0;
double instant_probability = Math.random();
for (int k = 0; k < 6; k++ ) {
probability_value = probability_value + probabilities[k];
if (probability_value>instant_probability) {
sum = sum + options[k];
break;
}
}
}
int x = (int)Math.round(Math.random()*(600*n-n)+n);
if( x>sum ) {
count = count + 1;
}
}
double probability = (double)count/(double)repeatcount;
return probability;
}
public static void main(String[] args) {
System.out.println(stat_prob(0.1,0.1,0.1,0.1,0.3,0.3));
System.out.println(geom_prob(0.1,0.1,0.1,0.1,0.3,0.3));
}
}
代码:
repeatcount = 100000
options = c(1,2,3,4,5,6)
n = 50
probabilities = c(1/10,1/10,1/10,1/10,3/10,3/10)
count = 0
for (i in 1:repeatcount) {
sum = 0
for (i in 1:n) {
probability_value=0
instant_probability = runif(1,0,1)
for (k in 1:6){
probability_value = probability_value + probabilities[k]
if (probability_value>instant_probability) {
sum = sum + options[k]
break
}
}
}
x = runif(1,n,600*n)
x
sum
if ( x> sum ) {
count = count + 1
}
}
count
probability = count/repeatcount
probability