【演算法】類比擲骰子

來源:互聯網
上載者:User

標籤:

類比擲骰子。以下代碼能夠計算每種兩個骰子之和的準確機率分布:

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.13888910 Probability of [7] is: 0.16666711 Probability of [8] is: 0.13888912 Probability of [9] is: 0.11111113 Probability of [10] is: 0.08333314 Probability of [11] is: 0.05555615 Probability of [12] is: 0.02777816 Experiment: 17 Probability of [0] is: 0.00000018 Probability of [1] is: 0.00000019 Probability of [2] is: 0.02775420 Probability of [3] is: 0.05554421 Probability of [4] is: 0.08337422 Probability of [5] is: 0.11113023 Probability of [6] is: 0.13889724 Probability of [7] is: 0.16675125 Probability of [8] is: 0.13883226 Probability of [9] is: 0.11108827 Probability of [10] is: 0.08330628 Probability of [11] is: 0.05551729 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

【演算法】類比擲骰子

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.