白二娃
之前《電腦報(bào)》刊登了一篇用VB計(jì)算圓周率π值的文章。使用了π/4=1-1/3+1/5+…+1/i,計(jì)算π的近似值,i值越大精度越高。這種算法由于不夠直觀,其實(shí)不太容易理解。我另外選了兩種計(jì)算π的算法:蒙特卡羅方法和直接測(cè)量法,并用Scratch編程來(lái)計(jì)算圓周率,這樣小朋友都能很容易理解圓周率的定義和計(jì)算了。
蒙特卡羅方法(Monte Carlo,簡(jiǎn)稱MC)是馮·諾依曼等人提出的統(tǒng)計(jì)模擬方法,蒙特卡羅這個(gè)名字來(lái)源于賭場(chǎng),表示這種算法的不確定性原理與賭博類似。
假設(shè)有一個(gè)邊長(zhǎng)為1的正方形區(qū)域,有一個(gè)圓和這個(gè)正方形內(nèi)切。我們知道正方形面積是邊長(zhǎng)a的平方,圓形面積是π乘以半徑R的平方。由于是內(nèi)切圓所以正方形邊長(zhǎng)等于2R,圓形和正方形面積的比值k等于π/4。
如果能夠知道k的值,就能得到π=4k,這就是估算圓周率的核心思想。
現(xiàn)在我們向矩形范圍內(nèi)隨機(jī)畫點(diǎn),任何位置被選中的概率都是相等的,圖中共投了1000個(gè)點(diǎn),經(jīng)過(guò)統(tǒng)計(jì)落在圓內(nèi)的點(diǎn)為787個(gè),由于投點(diǎn)是隨機(jī)的,所以可以近似認(rèn)為圓形和矩形的面積比k等于點(diǎn)數(shù)比,即k=787/1000=0.787,所以圓周率π=4k=4x0.787=3.148,至此圓周率π的估算已經(jīng)完成。
新建角色“圓心”和“筆”,“圓心”就在(0,0)畫一個(gè)點(diǎn),“筆”隱藏顯示。
在程序中我們?cè)O(shè)置了3個(gè)變量,“pi”存儲(chǔ)π值、“總投放點(diǎn)數(shù)”設(shè)置總數(shù)、“落在范圍內(nèi)的點(diǎn)”記錄在圓內(nèi)的點(diǎn)。
調(diào)用畫筆擴(kuò)展,重復(fù)執(zhí)行“總投放點(diǎn)數(shù)”次。在XY坐標(biāo)-90到90之間的方形區(qū)域隨機(jī)畫點(diǎn)。
判斷如果隨機(jī)畫的這個(gè)點(diǎn)到角色“圓心”的距離大于90不成立。即表示這個(gè)點(diǎn)在圓的范圍內(nèi)(含圓的邊)。將“落在范圍內(nèi)的點(diǎn)”加1。
循環(huán)完畢,用“落在范圍內(nèi)的點(diǎn)”除以“總投放點(diǎn)數(shù)”就獲得面積比k,乘以4就得到π值了。運(yùn)行時(shí)請(qǐng)打開加速模式,不然會(huì)運(yùn)算到天荒地老。
蒙特卡羅方法是一種依賴于重復(fù)性隨機(jī)采樣,進(jìn)而獲得數(shù)值解的建模方法。對(duì)于復(fù)雜曲線積分這種很難通過(guò)理論求解的情況,可以通過(guò)蒙特卡羅方法獲得一個(gè)近似解。我們用Scratch編程后多次運(yùn)行就可發(fā)現(xiàn),算出的π值偏差比較大,而提高“總投放點(diǎn)數(shù)”并不能很好地提升計(jì)算精度,這應(yīng)該是由于計(jì)算機(jī)產(chǎn)生的隨機(jī)數(shù)是偽隨機(jī)數(shù)造成的。
我們知道π的定義是圓的周長(zhǎng)與直徑的比值。
我們用Scratch畫出半個(gè)邊數(shù)超多(100000條邊)的多邊形。這個(gè)多邊形由于每條邊都很短,可以認(rèn)為近似是一個(gè)圓,這個(gè)半圓的終點(diǎn)到起點(diǎn)間的距離就是圓的直徑。邊長(zhǎng)乘以邊數(shù)就是這個(gè)圓的周長(zhǎng)。兩者相除就可以算出π的值了。
新建角色“起點(diǎn)”,在造型中背景放到最大后在中心點(diǎn)一個(gè)小點(diǎn)。移動(dòng)到(0,-160)作為起點(diǎn)位置。
對(duì)小貓編程。
設(shè)置“pi”記錄計(jì)算結(jié)果,通過(guò)控制“邊長(zhǎng)”(0.01)、“邊數(shù)”(100000)的大小控制近似圓形的大小,提高計(jì)算π值的精度,邊數(shù)越多π的精度應(yīng)該越高。
移動(dòng)到(0,-160)的起點(diǎn)位置,面向90度方向,重復(fù)執(zhí)行邊數(shù)除以2次,因?yàn)槲覀冎恍枰嬕粋€(gè)半圓用來(lái)測(cè)量直徑。畫正多邊形的方法《電腦報(bào)》以前已經(jīng)介紹過(guò)就是移動(dòng)“邊長(zhǎng)”步,左轉(zhuǎn)360除以“邊數(shù)”度。這樣畫出的半圓形終點(diǎn)到角色“起點(diǎn)”之間的距離就是圓的直徑。
邊長(zhǎng)乘以邊數(shù)就是圓的近似周長(zhǎng)。
將“pi”設(shè)為“邊長(zhǎng)”*“邊數(shù)”/到“起點(diǎn)”的距離。
要想看到最精確的計(jì)算結(jié)果,有一個(gè)小技巧,要點(diǎn)擊單獨(dú)放在代碼區(qū)的變量“pi”才行。計(jì)算結(jié)果為3.141592653072866與我們已知的π值相當(dāng)接近,說(shuō)明這個(gè)方法計(jì)算結(jié)果相當(dāng)精確。
這個(gè)方法的思維方法最為直接,就是測(cè)量出圓的周長(zhǎng)和直徑直接相除就可以得到π值。但是對(duì)于古人來(lái)說(shuō)周長(zhǎng)和直徑都很難精確測(cè)量,所以才有那么多數(shù)學(xué)家想方設(shè)法去提高π的計(jì)算精度,但是對(duì)于程序來(lái)說(shuō)這個(gè)直接的方法卻意外的容易和精確。
我們程序中設(shè)定的邊長(zhǎng)和邊數(shù)數(shù)值只是個(gè)經(jīng)驗(yàn)數(shù)值,只是因?yàn)楫嫵鰜?lái)的半圓大小比較合適。其實(shí)只要多邊形邊數(shù)超過(guò)100條邊時(shí)π值的精度就已經(jīng)達(dá)到3.141了,比蒙特卡羅方法效果好得多,隨著邊數(shù)的提高計(jì)算精度穩(wěn)步提升,而且邊長(zhǎng)對(duì)于π計(jì)算結(jié)果影響不大,只是影響視覺效果而已。