Nickyhw

          研究Java技術(shù),算法設計以及移動開發(fā)

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            2 隨筆 :: 0 文章 :: 0 評論 :: 0 Trackbacks

              1946年,美國拉斯阿莫斯國家實驗室的三位科學家John von Neumann,Stan Ulam 和 Nick Metropolis共同發(fā)明,被稱為蒙特卡洛方法。

              它的具體定義是:

              在廣場上畫一個邊長一米的正方形,在正方形內(nèi)部隨意用粉筆畫一個不規(guī)則的形狀,現(xiàn)在要計算這個不規(guī)則圖形的面積,怎么計算列?蒙特卡洛(Monte Carlo)方法告訴我們,均勻的向該正方形內(nèi)撒N(N 是一個很大的自然數(shù))個黃豆,隨后數(shù)數(shù)有多少個黃豆在這個不規(guī)則幾何形狀內(nèi)部,比如說有M個,那么,這個奇怪形狀的面積便近似于M/N,N越大,算出來的 值便越精確。在這里我們要假定豆子都在一個平面上,相互之間沒有重疊。

              蒙特卡洛方法可用于近似計算圓周率:讓計算機每次隨機生成兩 個0到1之間的數(shù),看這兩個實數(shù)是否在單位圓內(nèi)。生成一系列隨機點,統(tǒng)計單位圓內(nèi)的點數(shù)與總點數(shù),(圓面積和正方形面積之比為PI:1,PI為圓周率), 當隨機點取得越多(但即使取10的9次方個隨機點時,其結(jié)果也僅在前4位與圓周率吻合)時,其結(jié)果越接近于圓周率。

              (以上摘自《20世紀最偉大的10個算法》)


              讓我們來看一下這個圖:

           


              圖中黃色區(qū)域為一單位圓,半徑r=1。其外接正方形邊長為2。我們可以看到,外接正方形與坐標軸將該單位圓切成四等分,而每個小正方形的面積為1*1=1。這樣,為了求出小正方形里的扇形面積,我們利用計算機強大的計算能力,往小正方形里投入無數(shù)個隨機點。假設投進扇形里的點總數(shù)為c_sum,投進小正方形里的點(包含投進扇形的點)總數(shù)為sum,那么根據(jù)公式c_sum / sum = area / 1,即可計算出該扇形的面積 = c_sum / sum。由此可得到圓的面積area = c_sum / sum * 4。
              我們知道,單位圓的半徑r=1,所以實際上求單位圓的面積就是求出PI的數(shù)值。隨機點數(shù)量取值越大,那么PI值就越精確。

           1 /**
           2  * 利用蒙特卡洛算法(Mente Carlo Method)計算單位圓面積
           
          3  *
           4  */
           5 
           6 import java.util.Random;
           7 
           8 public class MonteCarloMethodTest
           9 {
          10     public static void main(String[] args)
          11     {
          12         int sum = 0;                    
          13         int c_sum = 0;                    
          14         double x;                        
          15         double y;                        
          16         Random ra = new Random();        
          17         
          18         int i = 0;
          19         while (i != 100000000)            
          20         {
          21             x = ra.nextDouble();
          22             y = ra.nextDouble();
          23             
          24             if (x * x + y * y <= 1)    
          25                 ++c_sum;
          26             ++sum;
          27             ++i;
          28         }
          29         
          30         double area = (double)c_sum / sum * 4;    
          31         System.out.println("area = " + area);
          32     }
          33 }

              在這個程序中,總共在小正方形里生成了100000000個隨機點。通過判斷生成的隨機點距離圓心點的距離來判斷生成的點是否在單位圓內(nèi)。
              運行10次,結(jié)果如下:
              area = 3.14172004
              area = 3.14182308
              area = 3.14190064
              area = 3.14139992
              area = 3.14176768
              area = 3.14177084
              area = 3.14142864
              area = 3.14176596
              area = 3.14191927
              area = 3.14172096
              我們知道,較為精確的PI數(shù)值為3.14159265……
              所以即使計算機已經(jīng)模擬到100000000個隨機點,也只能大致精確到小數(shù)點后3位,而為了模擬這100000000個點,我的Y560筆記本也平均要花費5秒的時間來進行運算,如果再增加幾個0……

              蒙特卡洛算法是1946年提出來的,當時沒有運行速度如此快的現(xiàn)代計算機。不過由于現(xiàn)代計算機的運算速度不斷提高,借助于其強大的計算能力,我們可以將蒙特卡洛運用在工程中的很多需要近似求解的地方。

           

          posted on 2012-06-27 00:30 Nickyhw 閱讀(4820) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 巴南区| 酒泉市| 介休市| 金阳县| 宜春市| 蚌埠市| 大安市| 平南县| 富蕴县| 怀来县| 靖宇县| 阳原县| 大同市| 叶城县| 芷江| 绿春县| 宣汉县| 上饶市| 新巴尔虎右旗| 鸡东县| 抚顺市| 榕江县| 长宁区| 区。| 玉山县| 霍城县| 卢氏县| 博湖县| 额济纳旗| 临澧县| 香港| 定安县| 福海县| 鸡西市| 兴宁市| 洛扎县| 肃北| 泗阳县| 商河县| 铅山县| 济南市|