【數學】通俗解釋布豐投針實驗過程及python仿真代碼

很鬱悶爲什麼網上的布豐投針都寫的這麼複雜,而且很多都是復讀機直接copy別人,其實這是個很精巧、有趣的實驗,所以打算自己寫一個布豐投針的介紹

故事背景

你在教室裏寫數學題,突然有個人,抱着一大盒針走過來,然後把針撒到地上,然後很淡定地點點頭說,“嗯,我知道π等於多少了”。

是不是覺得很神奇?!這跟π什麼關係?!!!

沒錯,這個人就是布豐。

實驗過程

這個實驗也很簡單,兩段距離爲D的平行線、一根長爲L的針(L≤D)
在這裏插入圖片描述
投針實驗就是把這根針扔到兩段平行線之間,然後統計針碰到平行線的次數,例如圖中的兩根針,紅色針就是碰到,黑色針就是沒碰到
在這裏插入圖片描述
哪這和π是怎麼扯上關係的呢?是從”針碰到平行線“的數學定義中推導得到的。我們先想辦法定義針的位置,取針的中點向最近的平行線做垂線,定義該垂線爲XX,該垂線與針的夾角爲θθ
因爲針是在兩段平行線之間,故
X[0,D/2]X\in[0, D/2]
同時因爲總能找到一個小於90°的角,故
θ[0,π/2]θ\in[0, π/2]

在這裏插入圖片描述
XXθθ與平行線可以組成一個直角三角形,所以斜邊的長度是X/cosθX/cosθ
在這裏插入圖片描述
因此,只要
X/cosθ<L/2X/cosθ < L/2
X<(L/2)cosθ即X < (L/2)*cosθ
的話(其實取≤也可以,影響不大),就說明針碰到了平行線,否則就說明沒碰到,下圖分別爲”沒碰到和“碰到”的情況
在這裏插入圖片描述
下面我們來表示出“針碰到平行線的概率”,即
P{X<L2cosθ}P\{X<\frac{L}{2}cosθ\}

求概率,本質就是比值,而因爲XXθθ是連續的,所以上面的比值可以等價於面積的比值

即,當XXθθ在其取值範圍內變化時,會生成無數個點,這些點的總面積爲S=D2π2=Dπ4S = \frac{D}{2} * \frac{π}{2} = \frac{D*π}{4} (由XXθθ的取值範圍決定)

在這無數個點中,有一些點滿足X<L2cosθX<\frac{L}{2}cosθ這一條件,這些點的面積記作S1S_1,所以

P{X<L2cosθ}=S1SP\{X<\frac{L}{2}cosθ\} = \frac{S1}{S}

那怎麼把S1S_1表示出來呢?因爲針的中心點和角度是沒關係的,所以我們可以假設中XXθθ是相互獨立的,且他們在各自的取值範圍內服從均勻分佈,所以可以寫成
在這裏插入圖片描述
剩下的就算微積分的事情了
在這裏插入圖片描述
所以可得
P{X<L2cosθ}=2LπDP\{X<\frac{L}{2}cosθ\} = \frac{2*L}{π*D}

接下來,我們就可以反向思維,把ππ表示出來
π=2LP{X<L2cosθ}Dπ = \frac{2*L}{P\{X<\frac{L}{2}cosθ\}*D}

所以,只要知道了LLDDP{X<L2cosθ}P\{X<\frac{L}{2}cosθ\}就可以算出ππ

那問題來了,P{X<L2cosθ}P\{X<\frac{L}{2}cosθ\}不是根據上面積分算出來的嗎?你這樣不就雞生蛋蛋生雞了?

其實P{X<L2cosθ}P\{X<\frac{L}{2}cosθ\}還可以通過做實驗的途徑得到,例如我投100次針,其中有50次針碰到了平行線,那麼P{X<L2cosθ}=50100=0.5P\{X<\frac{L}{2}cosθ\}=\frac{50}{100}=0.5

這樣一來,ππ也就能求出來了

這種通過做實驗來求積分的方法,就是大名鼎鼎的蒙特卡洛方法
(你也可以認爲是暴力求解積分哈哈哈)

以上,就是布豐投針實驗求ππ的過程

代碼實驗

import random
import numpy as np
from tqdm import tqdm

# 平行線距離
D = 2
# 針的長度
L = 1
# 實驗次數
exp_num = 100000000
# 觸碰次數
touch_num = 0
for i in tqdm(range(1, exp_num+1)):
    X = random.uniform(0, D / 2)
    theta = random.uniform(0, np.pi / 2)
    if X < (L/2)*np.cos(theta):
        touch_num += 1
# 計算π
P = touch_num/exp_num
print('π = {}'.format((2*L)/(P*D)))

結果爲:

π = 3.1412599467996216

大家可能會對theta = random.uniform(0, np.pi / 2)很疑問,我想求得是ππ,但是代碼中就已經給定ππ(即np.pi),這不就犯規了嗎?

其實不是,因爲代碼中我們要模擬現實的投針場景,所以theta = random.uniform(0, np.pi / 2)就是我們的現實,相當於是上帝提前設定好的,我們不知道的
我們的結果、我們想求的東西,就是希望去找到theta = random.uniform(0, np.pi / 2)中的ππ(即np.pi)是多少,它是我們的目標,我們希望結果儘可能的接近他

換句話說,如果我把theta = random.uniform(0, np.pi / 2)中的ππ(即np.pi)換成數字5的話(即改爲theta = random.uniform(0, 5 / 2)

我們輸出的結果就會非常接近5,因爲我們此時想要擬合的目標是5

運行下面的代碼(只改了theta那一行),輸出結果爲:π = 5.00038202918703

import random
import numpy as np
from tqdm import tqdm

# 平行線距離
D = 2
# 針的長度
L = 1
# 實驗次數
exp_num = 100000000
# 觸碰次數
touch_num = 0
for i in tqdm(range(1, exp_num+1)):
    X = random.uniform(0, D / 2)
    theta = random.uniform(0, 5 / 2)
    if X < (L/2)*np.cos(theta):
        touch_num += 1
# 計算π
P = touch_num/exp_num
print('π = {}'.format((2*L)/(P*D)))

ππ只是個外衣,不要被騙了哈哈哈

布豐投針給我們提供的是一種解決問題的思路,”通過數學推導與實驗(蒙特卡洛方法)的配合,求出難以直接計算得到的值“,我認爲這纔是這個實驗的巧妙之處~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章