Java運用蒙特卡洛方法計算圓周率

1、蒙特卡洛法:

蒙特卡羅方法又稱統計模擬法、隨機抽樣技術,是一種隨機模擬方法,以概率和統計理論方法爲基礎的一種計算方法,是使用隨機數(或更常見的僞隨機數)來解決很多計算問題的方法。將所求解的問題同一定的概率模型相聯繫,用電子計算機實現統計模擬或抽樣,以獲得問題的近似解。爲象徵性地表明這一方法的概率統計特徵,故借用賭城蒙特卡羅命名。
提出:
蒙特卡羅方法於20世紀40年代美國在第二次世界大戰中研製原子彈的“曼哈頓計劃”計劃的成員S.M.烏拉姆和J.馮·諾伊曼首先提出。數學家馮·諾伊曼用馳名世界的賭城—摩納哥的Monte Carlo—來命名這種方法,爲它蒙上了一層神祕色彩。在這之前,蒙特卡羅方法就已經存在。1777年,法國數學家布豐(Georges Louis Leclere de Buffon,1707—1788)提出用投針實驗的方法求圓周率π。這被認爲是蒙特卡羅方法的起源。

2、基本思想:

當所求解問題是某種隨機事件出現的概率,或者是某個隨機變量的期望值時,通過某種“實驗”的方法,以這種事件出現的頻率估計這一隨機事件的概率,或者得到這個隨機變量的某些數字特徵,並將其作爲問題的解。
工作過程
蒙特卡羅方法的解題過程可以歸結爲三個主要步驟:構造或描述概率過程;實現從已知概率分佈抽樣;建立各種估計量。
蒙特卡羅方法解題過程的三個主要步驟:
(1)構造或描述概率過程
對於本身就具有隨機性質的問題,如粒子輸運問題,主要是正確描述和模擬這個概率過 程,對於本來不是隨機性質的確定性問題,比如計算定積分,就必須事先構造一個人爲的概率過程,它的某些參量正好是所要求問題的解。即要將不具有隨機性質的問題轉化爲隨機性質的問題。
(2)實現從已知概率分佈抽樣
構造了概率模型以後,由於各種概率模型都可以看作是由各種各樣的概率分佈構成的,因此產生已知概率分佈的隨機變量(或隨機向量),就成爲實現蒙特卡羅方法模擬實驗的基本手段,這也是蒙特卡羅方法被稱爲隨機抽樣的原因。最簡單、最基本、最重要的一個概率分佈是(0,1)上的均勻分佈(或稱矩形分佈)。隨機數就是具有這種均勻分佈的隨機變量。隨機數序列就是具有這種分佈的總體的一個簡單子樣,也就是一個具有這種分佈的相互獨立的隨機變數序列。產生隨機數的問題,就是從這個分佈的抽樣問題。在計算機上,可以用物理方法產生隨機數,但價格昂貴,不能重複,使用不便。另一種方法是用數學遞推公式產生。這樣產生的序列,與真正的隨機數序列不同,所以稱爲僞隨機數,或僞隨機數序列。不過,經過多種統計檢驗表明,它與真正的隨機數,或隨機數序列具有相近的性質,因此可把它作爲真正的隨機數來使用。由已知分佈隨機抽樣有各種方法,與從(0,1)上均勻分佈抽樣不同,這些方法都是藉助於隨機序列來實現的,也就是說,都是以產生隨機數爲前提的。由此可見,隨機數是我們實現蒙特卡羅模擬的基本工具。
(3)建立各種估計量
一般說來,構造了概率模型並能從中抽樣後,即實現模擬實驗後,我們就要確定一個隨機變量,作爲所要求的問題的解,我們稱它爲無偏估計。建立各種估計量,相當於對模擬實驗的結果進行考察和登記,從中得到問題的解。
數學應用:
通常蒙特·卡羅方法通過構造符合一定規則的隨機數來解決數學上的各種問題。對於那些由於計算過於複雜而難以得到解析解或者根本沒有解析解的問題,蒙特·卡羅方法是一種有效的求出數值解的方法。一般蒙特·卡羅方法在數學中最常見的應用就是蒙特·卡羅積分。

3、Java運用模型計算圓周率:

原理:在數值積分法中,利用求單位圓的1/4的面積來求得Pi/4從而得到Pi。單位圓的1/4面積是一個扇形,它是邊長爲1單位正方形的一部分。只要能求出扇形面積S1在正方形面積S中佔的比例K=S1/S就立即能得到S1,從而得到Pi的值。怎樣求出扇形面積在正方形面積中佔的比例K呢?一個辦法是在正方形中隨機投入很多點,使所投的點落在正方形中每一個位置的機會相等看其中有多少個點落在扇形內。將落在扇形內的點數m與所投點的總數n的比m/n作爲k的近似值。P落在扇形內的充要條件是x^2+y^2<=1。


代碼:

package com.citi.com.citi;
import java.util.Random;
import java.util.Scanner;


public class MontePI {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("Please input times: ");
Scanner sc=new Scanner(System.in);
caculatePI(sc.nextInt());
}


public static void caculatePI(int countInSquarel) {
int countInCircle = 0, i, resulttimes;
double x, y; /* 座標 */
Random s = new Random();
for (resulttimes = 0; resulttimes < 10; resulttimes++) { /* 輸出十次結果 */
for (i = 1; i <= countInSquarel; i++) {
x = s.nextDouble(); /* 在0~1之間產生一個隨機x座標 */
y = s.nextDouble(); /* 在0~1之間產生一個隨機y座標 */
if (caculateAcreage(x,y)<= 1.0)
countInCircle++; /* 統計落入單位圓中的點數 */
}
System.out.println("The result of pai is " + (double) countInCircle / countInSquarel* 4); /* 計算出π的值 */
countInCircle = 0;
}
}

private static double caculateAcreage(double xPosition,double yPosition){
return xPosition*xPosition+yPosition*yPosition;
}
}

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