1. 程式人生 > >數學建模————統計問題之模擬(四)

數學建模————統計問題之模擬(四)

       模擬,顧名思義,就是利用計算機模擬研究物件,對於那些用數學公式或者規則描述的系統,計算機可以將其通過數值模擬出來,還能實現視覺化。就好比我們看的小說一樣,創造一個世界,需要有初始的人或物質,再加上法則(規則),那麼這個世界就會逐步成型,模擬也是如此,我們需要給這個模擬世界一個初始的狀態(包含應有的資料),然後告訴他運轉的規則。

       真實的系統往往存在著很多不確定因素 ,比如:要模擬某條道路的交通,我們就得知道路上的行車的情況,除了基本的交通規則之外,我們需要的是車輛的模擬。一般來說,我們都會給車流量一個分佈,這樣我們就相當於有了一個車輛生成器,然後通過行車規則,就可以完整的模擬出整條道路的交通。

       不過,大多數時候我們都只是設定幾個交通狀況指標,然後模擬不同時間的情況,就可以實現交通狀況的數值模擬。當然,有時候為了論文(觀賞)效果,還可以將整條道路分成很多個小塊,當車經過時就讓小塊發亮,這樣就可以看到整個交通的執行情況,這種方法我們叫做元胞自動機。

        既然是模擬系統,那麼就需要一個系統的推進方式,我們依此可以將模擬分為時間步長法事件步長法。時間步長法即將每經過一定時間步長就模擬一次活動,然後推進下去,而事件步長法即每發生一件事情就推進一次,當然這個步長也可以看做是每兩個事件之間的時間。

       上面介紹的模擬方法都講究推進,也就是說是動態的 ,除此之外還有靜態模擬。靜態模擬比較有名的是蒙特卡洛模擬

,下面給大家展示一道百度校招筆試題:
       在平面上有一組間距為d的平行線,將一根長度為l(l<d)的針任意擲在這個平面上,求此針與平行線中任意一根相交的概率,用高等數學(微積分、概率的方法)求解,基於布豐投針的結論,任選一種程式語言(C/C++, matlab, Python, Java),寫出模擬投針實驗(程式中允許把一個理想的π作為常量使用),求解圓周率。
注:前面的高等數學部分可以求解,已證明這個概率=2l / πd,另外針中點到相鄰平行線的距離x≤l/2sinφ,l是針的長度,φ是針與平行線的夾角。

       現在我們知道了規則,那就是x≤l/2sinφ,為了模擬各種情況,我們現在需要做的就是對未知量x和未知夾角φ進行隨機模擬,然後計算符合規則的概率,最後依次計算圓周率。


clc;clear;close all;
d = 2;%設定平行線之間的距離
l = 1;%設定針的長度
n = 1000;%設定投針個數
beta = 0 : 0.002 : pi;
plot(beta, l/2*sin(beta), 'k-')%繪出l/2*sin(φ)曲線
axis([0, pi, 0, d/2])%橫座標範圍設在0~pi,縱座標範圍設在0~d/2
title('蒲豐投針實驗')
hold on
beta = rand(1, n) * pi;%隨機生成n個角度(0~180度)
x = (d/2) * rand(1, n);%在平行線中線以下生成n個針中心
m = 0;
for i = 1 : n
    if x(i) <= l/2 * sin(beta(i))
        m = m + 1;%符合條件就增計數
        plot(beta(i), x(i), '.r')%將符合條件的針以紅點形式畫在圖中
        pause(0.00001)
    else
        plot(beta(i),x(i),'.b')%將不符合條件的針以藍點形式畫在圖中
       pause(0.00001)
    end
end
p = m/n;%計算概率
pai = 2*l / (d*p);%計算圓周率
disp(['圓周率為:',num2str(pai)])



結果如下: