你也可以算出圓周率的

一年一度的圓周率日就要到了,是的,就是3月14日,因為它與圓周率π的前幾位3.14的數字一樣。

我們知道,傳說中祖沖之計算圓周率用的是“割圓術”的改進方法,可惜我們大多數現代人的腦子已經無法理解這種方法了。使用其他的複雜公式也有,但人的腦子更不容易理解,但有一個異想天開的方法你知道嗎?任何人可以簡單地去計算出Pi呢(下面我們都用Pi來代替圓周率π吧,好寫好認,:p)。

這個方法源自概率論的基礎,叫做蒙特卡洛法,形象一點的話我們也可以把它稱為隨機落點法,我們先說說它的原理:

我們先看看下面這張圖


你也可以算出圓周率的 - 隨機落點算法 - 致即將到來的圓周率日

假設有圖中的一個正方形和一個剛好套在它中間的圓形,可以很直觀地看出:圓形的半徑如果是R的話,正方形的邊長就是2R。

圓形的面積根據公式是Pi乘以R的平方,也就是 Pi × R × R = PiR²

正方形的面積根據公式是邊長的平方,也就是(2R)×(2R)= 4R²

把兩個式子相除一下,可以很容易地推算出來,Pi = (圓形的面積 ÷ 正方形的面積)× 4


這樣,就巧妙地把計算Pi值的問題轉換成計算符合上面圖中條件的圓形與正方形的面積之比的計算了。


這時候,概率論可以出場發揮作用了,以及有了計算機之後,我們有的“隨機數”這個武器!


假設我們隨機在正方形範圍內畫一個點,那麼這個點有可能落在圓形之中,也有可能落在圓形之外;然後我們重複這個動作,從概率論上來說,如果進行無限多次,那麼落在圓形中的點的個數與所有已經畫的點的個數之比,就應該是圓形的面積和正方形的面積之比。看看下面這張圖是不是就好理解了?


你也可以算出圓周率的 - 隨機落點算法 - 致即將到來的圓周率日

想想當裡面的點數足夠多的時候,就可以覆蓋滿整個原型和正方形。俗話說:“以點帶面”,這時候就可以理解成無數多的點組成了圓形和正方形的面積。


好了,那麼下面我們看看用計算機程序來實現這種方法計算圓周率的效果吧!我們這次選用Go語言(Golang)來實現這個算法,因為Go語言相對速度較快(比Python和Java等解釋型語言要快得多),編寫起來又比C語言更容易看懂。

<code>package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    // 初始化一下隨機數種子
    rand.Seed(time.Now().Unix())

    // inCircleCount代表落在圓形中的點的數量
    inCircleCount := 0

    var x, y float64
    var Pi float64

    // 一共循環產生 1 萬個隨機點
    for i := 0; i         // 產生兩個取值為 0 到 1 之間的小數,代表隨機生成點的 X 和 Y 座標

        x = rand.Float64()
        y = rand.Float64()

        if x*x+y*y             inCircleCount++
        }

        // 每生成1000個隨機點之後就看看圓周率的計算結果是多少
        if i%1000 == 0 {
            Pi = (4.0 * float64(inCircleCount)) / float64(i)
            fmt.Println("計算到", i, "次時,圓周率是:", Pi)
        }
    }
}/<code>

這段程序的運行結果是:


你也可以算出圓周率的 - 隨機落點算法 - 致即將到來的圓周率日

可以看出來,計算出來的圓周率Pi值越來越接近於我們所熟知的數字:3.1415……


神奇吧,為什麼說人也可以算出來呢?假想在地上用粉筆畫一個那樣的正方形和圓形,然後我們隨性地往裡扔沙包吧!很童真的畫面吧?


分享到:


相關文章: