编译语言:java;编译环境:《算法第四版》官网编译器 ,附上地址连接:http://algs4.cs.princeton.edu/windows/
1、首先做了一个模拟投单个骰子随机事件
import edu.princeton.cs.algs4.StdOut; import edu.princeton.cs.algs4.StdRandom; import edu.princeton.cs.algs4.Counter; public class Rolls { public static void main(String[] args) { int T = Integer.parseInt(args[0]); //初始化赋值投掷次数,模拟次数越多越接近理论值 int SIDES = 6; //定义骰子的6个面 Counter[] rolls = new Counter[SIDES+1]; for(int i = 0;i <= SIDES;i++) { rolls[i] = new Counter("point:"+i); } for(int t = 0;t < T;t++) { int result = StdRandom.uniform(1,SIDES+1); //获取1~6中的随机数 rolls[result].increment(); } for(int i = 1;i <= SIDES;i++) StdOut.println(rolls[i]); } }
运行后的结果如下图所示:
从运行结果可以看出,当模拟次数到达10000次的时候,每个点数出现的频率虽有出入,但是大致接近;如果模拟次数够多就可以无限接近理论值。
2、接下来我们模拟投掷两个骰子,以及各可能点数出现的概率。
import edu.princeton.cs.algs4.StdOut; import edu.princeton.cs.algs4.StdRandom; public class TwoRolls {
/*
*投掷两个骰子出现可能点数的理论概率
*/ public static void accurate() { int SIDES = 6; double[] dist = new double[2*SIDES+1]; for(int i = 1;i <= SIDES;i++) { for(int j = 1;j <= SIDES;j++) { dist[i+j] += 1.0; } } for(int k = 2;k <= 2*SIDES;k++) { dist[k] /= 36.0; StdOut.println("Sum="+k+" probability:"+dist[k]); } }
/*
*模拟投掷两个骰子N次,出现可能点数的实际概率
*/
public static void simulation(int N) { int SIDES = 6; double[] dist2 = new double[2*SIDES+1]; for(int i = 0;i < N;i++) { int a = StdRandom.uniform(1,7); int b = StdRandom.uniform(1,7); dist2[a+b] += 1; } for(int k = 2;k <= 2*SIDES;k++) { dist2[k] /= N; StdOut.println("Sum="+k+" simulation:"+dist2[k]); } } public static void main(String[] args) { accurate(); StdOut.println("****************************************************"); simulation(1000000); } }
经过多次的实验发现,当模拟投掷次数大于10^6时,实验数据概率和准确数据概率吻合程度达到小数点后三位。