zoukankan      html  css  js  c++  java
  • 【算法】模拟掷骰子

    模拟掷骰子。以下代码能够计算每种两个骰子之和的准确概率分布:

    int SIDES = 6;
    double[] dist = new double[2*SIDES+1];
    for (int i = 1; i <= SIDES; i++) 
        for (int j = 1; i <= SIDES; j++)
            dist[i+j] += 1.0;
    
    for (int k = 2; k <= 2*SIDES; k++)
        dist[k] /= 36.0;
    

     dist[i] 的值就是两个骰子之和为i的概率。用实验模拟N次掷骰子,并在计算两个1到

     6之间的随机整数之和时记录每个值的出现频率以验证它们的概率。N要多大才能够保证你

     的经验数据和准确数据的吻合程度达到小数点后三位?

    实验代码:

      1 package com.beyond.algs4.experiment;
      2 
      3 import java.math.BigDecimal;
      4 
      5 import com.beyond.algs4.lib.StdRandom;
      6 
      7 
      8 public class Sides {
      9 
     10     private static int SIDES = 6;
     11     
     12     private double[] dist = new double[2*SIDES + 1];
     13     
     14     public double[] getDist() {
     15         return dist;
     16     }
     17 
     18     public void setDist(double[] dist) {
     19         this.dist = dist;
     20     }
     21 
     22     public void probability() {
     23         for (int i = 1; i <= SIDES; i++) {
     24            for (int j = 1; j <= SIDES; j++) {
     25                dist[i + j] += 1.0;
     26            } 
     27         }
     28         for (int k = 2; k <= 2*SIDES; k++) {
     29             dist[k] /= 36.0;
     30         }
     31     }
     32     
     33     public void print() {
     34         for (int i = 0; i < dist.length; i++) {
     35             System.out.println(
     36                     String.format("Probability of [%d] is: %f", i, dist[i]));
     37         }
     38     }
     39     
     40     public static class Emulator {
     41         private int N = 100;
     42         
     43         private double[] dist = new double[2*SIDES + 1];
     44         
     45         public int getN() {
     46             return N;
     47         }
     48 
     49         public void setN(int n) {
     50             N = n;
     51         }
     52 
     53         public double[] getDist() {
     54             return dist;
     55         }
     56 
     57         public void setDist(double[] dist) {
     58             this.dist = dist;
     59         }
     60 
     61         public void emulator() {
     62             for (int i = 0; i < N; i++) {
     63                 int a = StdRandom.uniform(1, 7);
     64                 int b = StdRandom.uniform(1, 7);
     65                 dist[a + b] += 1.0;
     66             }
     67             for (int k = 2; k <= 2*SIDES; k++) {
     68                 dist[k] /= N;
     69             }
     70         }        
     71         
     72         public int n(Sides sides) {
     73             for (int i = 1; i <= 100; i++) {
     74                 this.setN(new Double(Math.pow(10, i)).intValue() * this.N);
     75                 this.emulator();
     76                 boolean appr = true;
     77                 for (int k = 2; k <= 2*SIDES; k++) {
     78                     double s = this.getDist()[k];
     79                     BigDecimal bs = new BigDecimal(s);
     80                     double s1 = bs.setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
     81                     double t = sides.getDist()[k];
     82                     BigDecimal bt = new BigDecimal(t);
     83                     double t1 = bt.setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
     84                     if (s1 != t1) {
     85                         appr = false;
     86                         break;
     87                     }
     88                 }
     89                 if (appr) {
     90                     return this.getN();   
     91                 }
     92             }
     93             return 0;
     94         }
     95         
     96         public void print() {
     97             for (int i = 0; i < dist.length; i++) {
     98                 System.out.println(
     99                         String.format("Probability of [%d] is: %f", i, dist[i]));
    100             }
    101         }
    102         
    103         
    104     }
    105     
    106     public static void main(String[] args) {
    107         Sides sides = new Sides();
    108         sides.probability();
    109 
    110         Emulator e = new Emulator();
    111         int N = e.n(sides);
    112         System.out.println(String.format("The N is: %d", N));
    113         System.out.println("Actual: ");
    114         sides.print();
    115         System.out.println("Experiment: ");
    116         e.print();
    117     }
    118 
    119 }


    实验结果:

     1 The N is: 100000000
     2 Actual: 
     3 Probability of [0] is: 0.000000
     4 Probability of [1] is: 0.000000
     5 Probability of [2] is: 0.027778
     6 Probability of [3] is: 0.055556
     7 Probability of [4] is: 0.083333
     8 Probability of [5] is: 0.111111
     9 Probability of [6] is: 0.138889
    10 Probability of [7] is: 0.166667
    11 Probability of [8] is: 0.138889
    12 Probability of [9] is: 0.111111
    13 Probability of [10] is: 0.083333
    14 Probability of [11] is: 0.055556
    15 Probability of [12] is: 0.027778
    16 Experiment: 
    17 Probability of [0] is: 0.000000
    18 Probability of [1] is: 0.000000
    19 Probability of [2] is: 0.027754
    20 Probability of [3] is: 0.055544
    21 Probability of [4] is: 0.083374
    22 Probability of [5] is: 0.111130
    23 Probability of [6] is: 0.138897
    24 Probability of [7] is: 0.166751
    25 Probability of [8] is: 0.138832
    26 Probability of [9] is: 0.111088
    27 Probability of [10] is: 0.083306
    28 Probability of [11] is: 0.055517
    29 Probability of [12] is: 0.027807

    结果分析:
    多次运行,N值一般为100000000,也有不稳定的时候是其他数值。

    补充说明:

    1. 以N=100为初始值,循环执行计算模拟N次的概率情况,如果吻合度不满足则N以10倍递增直至找到合适的N值。(有待改进,采用while(find))

    2. “吻合程度达到小数点后三位”的实现方式采用小数点后三位ROUND_DOWN的方式,有待改进

    3. N值并非每次运行皆为100000000的稳定结果,可适当随机多次执行,以分析N值的分布情况

    参考资料:

    算法 第四版  谢路云 译 Algorithms Fourth Edition [美] Robert Sedgewick, Kevin Wayne著

    http://algs4.cs.princeton.edu/home/

    源码下载链接:

    http://pan.baidu.com/s/1c0jO8DU

  • 相关阅读:
    2.6、实战案例(三)
    2.5、实战案例(二)
    2.4、实战案例(一)
    2.3、视频采集(二):分辨率、摄像头切换、帧率、滤镜
    2.2、视频采集(一):初步采集
    2.1、列举媒体设备
    1.0、本章导读
    linux 下搭建vsftpd
    解决.net core 3.1跨域问题
    SQLServer for linux安装
  • 原文地址:https://www.cnblogs.com/richaaaard/p/4576787.html
Copyright © 2011-2022 走看看