數學課上到這部分,依據大數法則,試驗的次數越多,結果會越相似於常態分佈,但丟硬幣100次都嫌累了,根本沒辦法看出甚麼所以然來,這時電腦就好用了,寫個小程式,數分鐘內幫你丟五億次硬幣! 還可以更多呢!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
 * Bernoulli Trial simulation
 * By C++
 * License MIT
 * 2017/09/19 oxygen
 */

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>

using namespace std;

//Global Variable
unsigned long long sample = 0,run_time = 0;

void init()
{
    fstream fp;
    fp.open("data.txt",ios::out);
    fp<<"id,true,false,True-rate,False-rate\n";
    fp.close();

    srand( (unsigned)time(NULL));
    cout<<"Program is running...\n";
}

bool Random()
{
    unsigned int ran = (int)((rand() / (RAND_MAX+1.0)) * (10 - 1 + 1.0) + 1);
    if(ran % 2 == 0)
        return true;
    return false;
}

void write_file(const int id,const unsigned long long True_number,const unsigned long long False_number)
{
    fstream fp;
    fp.open("data.txt",ios::out|ios::app);
    fp<<id<<","<<True_number<<","<<False_number<<","<<(True_number/(double)run_time)*100<<"%,"<<(False_number/(double)run_time)*100<<"%\n";
    fp.close();
}

int main()
{
    cout<<"How many times do yo want to run? >";
    cin >> sample;
    cout<<"How many times do yo want to run in one sample(n)? >";
    cin >> run_time;

    init();

    for(int c=0; c<sample; c++)
    {
        unsigned long long True_number = 0,False_number = 0;
        for(unsigned long long i=0; i<run_time; i++)
        {
            if(Random())
                True_number++;
            else
                False_number++;
        }
        write_file(c+1,True_number,False_number);
    }

    cout<<"Complete!\n";
}

解釋一下程式碼

init() 是程式一開始執行的函式,會把輸出檔案的標題輸出好,並初始化亂數器。

Random() 是最主要的部份,會隨機取出1~10的數字,如果是偶數則當作成功,回傳 true ,若是奇數則做為失敗,回傳 false。

write_file() 很簡單,把每一筆計算過的結果寫入檔案,參數需傳入[樣本編號][成功次數][失敗次數],他便會算出比率並寫入檔案。

main() 會先詢問使用者要執行幾回,每回有幾次試驗,輸入完後就會執行 init() 做初始化,隨後開始自動計數,每當 Random() 回傳 true 成功加一,回傳 false 失敗加一,直到達到使用者設定的次數,變數因為希望可以儲存很大的數字,所以我宣告 unsigned long long,理論上可以儲存到 18446744073709551615 這麼大的數字,但我實際測試到十四億就不行了,還在找原因中……

我把程式寫完後就遠端送到 Linux 去處理,性能比較好些,於是我也寫了 Makefile。

1
2
3
4
5
# Makefile of Bernoulli Trial simulation
all:Bernoulli-Trial-simulation.cpp
	g++ Bernoulli-Trial-simulation.cpp -o Bernoulli-Trial-simulation
clean:
	rm -f Bernoulli-Trial-simulation

超簡單的 Makefile XD就只是編譯和移除兩行指令而已,但能只打 make 就編譯還是比較方便 !