




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、解析Monte-Carlo算法(基本原理,理論基礎(chǔ),應(yīng)用實(shí)踐)2009-05-29 00:17 by EricZhang(T2噬菌體), 6109 visits, 網(wǎng)摘, 收藏, 編輯 引言 最近在和同學(xué)討論研究Six Sigma(六西格瑪)軟件開(kāi)發(fā)方法及CMMI相關(guān)問(wèn)題時(shí),遇到了需要使用Monte-Carlo算法模擬分布未知的多元一次概率密度分布問(wèn)題。于是花了幾天時(shí)間,通過(guò)查詢相關(guān)文獻(xiàn)資料,深入研究了一下Monte-Carlo算法,并以實(shí)際應(yīng)用為背景進(jìn)行了一些實(shí)驗(yàn)。 在研究
2、和實(shí)驗(yàn)過(guò)程中,發(fā)現(xiàn)Monte-Carlo算法是一個(gè)非常有用的算法,在許多實(shí)際問(wèn)題中,都有用武之地。目前,這個(gè)算法已經(jīng)在金融學(xué)、經(jīng)濟(jì)學(xué)、工程學(xué)、物理學(xué)、計(jì)算科學(xué)及計(jì)算機(jī)科學(xué)等多個(gè)領(lǐng)域廣泛應(yīng)用。而且這個(gè)算法本身并不復(fù)雜,只要掌握概率論及數(shù)理統(tǒng)計(jì)的基本知識(shí),就可以學(xué)會(huì)并加以應(yīng)用。由于這種算法與傳統(tǒng)的確定性算法在解決問(wèn)題的思路方面截然不同,作為計(jì)算機(jī)科學(xué)與技術(shù)相關(guān)人員以及程序員,掌握此算法,可以開(kāi)闊思維,為解決問(wèn)題增加一條新的思路。 基于以上原因,我有了寫(xiě)這篇文章的打算,一是回顧總結(jié)這幾天的研究和實(shí)驗(yàn),加深印象,二是和朋友們分享此算法以及我的
3、一些經(jīng)驗(yàn)。 這篇文章將首先從直觀的角度,介紹Monte-Carlo算法,然后介紹算法基本原理及數(shù)理基礎(chǔ),最后將會(huì)和大家分享幾個(gè)基于Monte-Carlo方法的有意思的實(shí)驗(yàn)。所以程序?qū)⑹褂肅#實(shí)現(xiàn)。 閱讀本文需要有一些概率論、數(shù)理統(tǒng)計(jì)、微積分和計(jì)算復(fù)雜性的基本知識(shí),不過(guò)不用太擔(dān)心,我將盡量避免過(guò)多的數(shù)學(xué)描述,并在適當(dāng)?shù)牡胤綄?duì)于用到的數(shù)學(xué)知識(shí)進(jìn)行簡(jiǎn)要的說(shuō)明。Monte-Carlo算法引導(dǎo) 首先,我們來(lái)看一個(gè)有意思的問(wèn)題:
4、在一個(gè)1平方米的正方形木板上,隨意畫(huà)一個(gè)圈,求這個(gè)圈的面積。 我們知道,如果圓圈是標(biāo)準(zhǔn)的,我們可以通過(guò)測(cè)量半徑r,然后用 S = pi * r2 來(lái)求出面積??墒牵覀儺?huà)的圈一般是不標(biāo)準(zhǔn)的,有時(shí)還特別不規(guī)則,如下圖是我畫(huà)的巨難看的圓圈。圖1、不規(guī)則圓圈 顯然,這個(gè)圖形不太可能有面積公式可以套用,也不太可能用解析的方法給出準(zhǔn)確解。不過(guò),我們可以用如下方法求這個(gè)圖形的面積: 假設(shè)我手里有一支飛鏢,我將飛鏢擲向木板。并且,
5、我們假定每一次都能擲在木板上,不會(huì)偏出木板,但每一次擲在木板的什么地方,是完全隨機(jī)的。即,每一次擲飛鏢,飛鏢扎進(jìn)木板的任何一點(diǎn)的概率的相等的。這樣,我們投擲多次,例如100次,然后我們統(tǒng)計(jì)這100次中,扎入不規(guī)則圖形內(nèi)部的次數(shù),假設(shè)為k,那么,我們就可以用 k/100 * 1 近似估計(jì)不規(guī)則圖形的面積,例如100次有32次擲入圖形內(nèi),我們就可以估計(jì)圖形的面積為0.32平方米。 以上這個(gè)過(guò)程,就是Monte-Carlo算法直觀應(yīng)用例子。 非形式化地說(shuō),Monte-Carlo算法
6、泛指一類算法。在這些算法中,要求解的問(wèn)題是某隨機(jī)事件的概率或某隨機(jī)變量的期望。這時(shí),通過(guò)“實(shí)驗(yàn)”方法,用頻率代替概率或得到隨機(jī)變量的某些數(shù)字特征,以此作為問(wèn)題的解。 上述問(wèn)題中,如果將“投擲一次飛鏢并擲入不規(guī)則圖形內(nèi)部”作為事件,那么圖形的面積在數(shù)學(xué)上等價(jià)于這個(gè)事件發(fā)生的概率(稍后證明),為了估計(jì)這個(gè)概率,我們用多次重復(fù)實(shí)驗(yàn)的方法,得到事件發(fā)生的頻率 k/100 ,以此頻率估計(jì)概率,從而得到問(wèn)題的解。 從上述可以看出,Monte-Carlo算法區(qū)別于確定性算法,它的解不一定是
7、準(zhǔn)確或正確的,其準(zhǔn)確或正確性依賴于概率和統(tǒng)計(jì),但在某些問(wèn)題上,當(dāng)重復(fù)實(shí)驗(yàn)次數(shù)足夠大時(shí),可以從很大概率上(這個(gè)概率是可以在數(shù)學(xué)上證明的,但依賴于具體問(wèn)題)確保解的準(zhǔn)確或正確性,所以,我們可以根據(jù)具體的概率分析,設(shè)定實(shí)驗(yàn)的次數(shù),從而將誤差或錯(cuò)誤率降到一個(gè)可容忍的程度。 上述問(wèn)題中,設(shè)總面積為S,不規(guī)則圖形面積為s,共投擲n次,其中擲在不規(guī)則圖形內(nèi)部的次數(shù)為k。根據(jù)伯努利大數(shù)定理,當(dāng)試驗(yàn)次數(shù)增多時(shí),k/n依概率收斂于事件的概率s/S。下面給出嚴(yán)格證明: 上述證明從數(shù)學(xué)上說(shuō)明用頻率估
8、計(jì)不規(guī)則圖形面積的合理性,進(jìn)一步可以給出誤差分析,從而選擇合適的實(shí)驗(yàn)次數(shù)n,以將誤差控制在可以容忍的范圍內(nèi),此處從略。 從上面的分析可以看出,Monte-Carlo算法雖然不能保證解一定是準(zhǔn)確和正確,但并不是“撞大運(yùn)”,其正確性和準(zhǔn)確性依賴概率論,有嚴(yán)格的數(shù)學(xué)基礎(chǔ),并且通過(guò)數(shù)學(xué)分析手段對(duì)實(shí)驗(yàn)加以控制,可以將誤差和錯(cuò)誤率降至可容忍范圍。Monte-Carlo算法的數(shù)理基礎(chǔ) 這一節(jié)討論Monte-Carlo算法的數(shù)理基礎(chǔ)。
9、; 首先給出三個(gè)定義:優(yōu)勢(shì),一致,偏真。這三個(gè)定義在后面會(huì)經(jīng)常用到。 1) 設(shè)p為一個(gè)實(shí)數(shù),且0.5<p<1。如果一個(gè)Monte-Carlo方法對(duì)問(wèn)題任一實(shí)例的得到正確解的概率不小于p,則該算法是p正確的,且p-0.5叫做此算法的優(yōu)勢(shì)。 2) 如果對(duì)于同一實(shí)例,某Monte-Carlo算法不會(huì)給出不同的解,則認(rèn)為該算法時(shí)一致的。 3) 如果某個(gè)解判定問(wèn)題的Monte-Carlo算法,當(dāng)返回true時(shí)是一定
10、正確的。則這個(gè)算法時(shí)偏真的。注意,這里沒(méi)有定義“偏假”,因?yàn)椤捌佟焙推媸堑葍r(jià)的。因?yàn)橹灰Q算法返回的true和false,“偏假”就變成偏真了。 下面,我們討論Monte-Carlo算法的可靠性和誤差分析。 總體來(lái)說(shuō),適用于Monte-Carlo算法的問(wèn)題,比較常見(jiàn)的有兩類。一類是問(wèn)題的解等價(jià)于某事件概率,如上述求不規(guī)則圖形面積的問(wèn)題;另一類是判定問(wèn)題,即判定某個(gè)命題是否為真,如主元素存在性判定和素?cái)?shù)測(cè)試問(wèn)題。
11、 先來(lái)分析第一類。對(duì)于這類問(wèn)題,通常的方法是通過(guò)大量重復(fù)性實(shí)驗(yàn),用事件發(fā)生的頻率估計(jì)概率。之所以能這樣做的數(shù)學(xué)基礎(chǔ),是伯努利大數(shù)法則:事件發(fā)生的頻率依概率收斂于事件的概率p。這個(gè)法則從數(shù)學(xué)生嚴(yán)格描述了頻率的穩(wěn)定性,直觀意義就是當(dāng)實(shí)驗(yàn)次數(shù)很大時(shí),頻率與概率偏差很大的概率非常小。此類問(wèn)題的誤差分析比較繁雜,此處從略。有興趣的朋友可以參考相關(guān)資料。 接著,我們分析第二類問(wèn)題。這里,我們只關(guān)心一致且偏真的判定問(wèn)題。下面給出這類問(wèn)題的正確率分析: 由以上分析可以看到,對(duì)于一致偏真的Mo
12、nte-Carlo算法,即使調(diào)用一次得到正確解的概率非常小,通過(guò)多次調(diào)用,其正確率會(huì)迅速提高,得到的結(jié)果非??煽?。例如,對(duì)一個(gè)q為0.5的問(wèn)題,假設(shè)p僅為0.01,通過(guò)調(diào)用1000次,其正確率約為0.9999784,幾乎可以認(rèn)為是絕對(duì)準(zhǔn)確的。重要的是,使用Monte-Carlo算法解判定問(wèn)題,其正確率不隨問(wèn)題規(guī)模而改變,這就使得僅需要損失微乎其微的正確性,就可以將算法復(fù)雜度降低一個(gè)數(shù)量級(jí),在后面中可以看到具體的例子。應(yīng)用實(shí)例一:使用Monte-Carlo算法計(jì)算定積分 計(jì)算定積分是金融、經(jīng)濟(jì)、工程等領(lǐng)域?qū)嵺`中經(jīng)常遇到的問(wèn)題。通常,計(jì)算
13、定積分的經(jīng)典方法是使用Newton-Leibniz公式: 這個(gè)公式雖然能方便計(jì)算出定積分的精確值,但是有一個(gè)局限就是要首先通過(guò)不定積分得到被積函數(shù)的原函數(shù)。有的時(shí)候,求原函數(shù)是非常困難的,而有的函數(shù),如f(x) = (sinx)/x,已經(jīng)被證明不存在初等原函數(shù),這樣,就無(wú)法用Newton-Leibniz公式,只能另想辦法。 下面就以f(x) = (sinx)/x為例介紹使用Monte-Carlo算法計(jì)算定積分的方法。首先需要聲明,f(x) = (sinx)/x在整個(gè)實(shí)數(shù)域是可
14、積的,但不連續(xù),在x = 0這一點(diǎn)沒(méi)有定義。但是,當(dāng)x趨近于0其左右極限都是1。為了嚴(yán)格起見(jiàn),我們補(bǔ)充定義當(dāng)x = 0時(shí)f(x) = 1。另外為了需要,這里不加證明地給出f(x)的一些性質(zhì):補(bǔ)充x = 0定義后,f(x)在負(fù)無(wú)窮到正無(wú)窮上連續(xù)、可積,并且有界,其界為1,即|f(x)| <= 1,當(dāng)且僅當(dāng)x = 0時(shí)f(x) = 1。 下面開(kāi)始介紹Monte-Carlo積分法。為了便于比較,在本節(jié)我們除了介紹使用Monte-Carlo方法計(jì)算定積分外,同時(shí)也探討和實(shí)現(xiàn)數(shù)值計(jì)算中常用的插值積分法,并通過(guò)實(shí)驗(yàn)結(jié)果數(shù)據(jù)對(duì)兩者的效率和精確
15、性進(jìn)行比較。1、插值積分法 我們知道,對(duì)于連續(xù)可積函數(shù),定積分的直觀意義就是函數(shù)曲線與x軸圍成的圖形中,y>0的面積減掉y<0的面積。那么一種直觀的數(shù)值積分方法是通過(guò)插值方法,其中最簡(jiǎn)單的是梯形法則:用以f(a)和f(b)為底,x軸和f(a)、f(b)連線為腰組成的梯形面積來(lái)近似估計(jì)積分。如下圖所示。圖2、梯形插值 如圖2所示,藍(lán)色部分是x1到x2積分的精確面積,而在梯形插值中,用橙色框所示的梯形面積近似估計(jì)積分值。
16、 顯然,梯形法則的效果一般,而且某些情況下偏差很大,于是,有人提出了一種改進(jìn)的方法:首先將積分區(qū)間分段,然后對(duì)每段計(jì)算梯形插值再加起來(lái),這樣精度就大大提高了。并且分段越多,精度越高。這就是復(fù)化梯形法則。 除了梯形插值外,還有許多插值積分法,比較常見(jiàn)的有Sinpson法則,當(dāng)然對(duì)應(yīng)的也有復(fù)化Sinpson法則。下面給出四種插值積分的公式: 下面是四種插值積分法的程序代碼,用C#編寫(xiě)。view source print?01using System; 02using
17、System.Collections.Generic; 03using System.Linq; 04using System.Text; 05 06namespace MonteCarlo.Integration 07 08 / <summary> 09 / 數(shù)值法求積分 10 / 被積函數(shù)為 f(x) = (sin x)/x 11 / </summary&g
18、t; 12 public class NumericalIntegrator 13 14 / <summary> 15 / 梯形法則求積分 16 / 積分公式為:(b - a) / 2) * f(a) + f(b
19、) 17 / </summary> 18 / <param name="a">積分下限</param> 19 / <param name="b">積分上限</param> 20
20、60; / <returns>積分值</returns> 21 public static double TrapezoidalIntegrate(double a, double b) 22 23
21、;return (b - a) / 2) * (Math.Sin(a) / a + Math.Sin(b) / b); 24 25 26 / <summary> 27 / 復(fù)化梯形法則求積分 28 &
22、#160; / 積分公式為:累加(xi - xi-1) / 2) * f(xi) + f(xi-1) (i=1,2,.,n) 29 / </summary> 30 / <param name="a">積分下限</param> 31 / &l
23、t;param name="b">積分上限</param> 32 / <param name="n">分段數(shù)量</param> 33 / <returns>積分值</returns> 34 public stat
24、ic double ComplexTrapezoidalIntegrate(double a, double b, int n) 35 36 double result = 0; 37 for (int i = 0; i
25、 < n; i+) 38 39 double xa = a + i * (b - a) / n;/區(qū)間積分下限 40
26、 double xb = xa + (b - a) / n;/區(qū)間積分上限 41 42 result += (xb - xa) / 2) * (Math.Sin(xa) / xa + Math.Sin(xb) / xb); 43
27、60; 44 45 return result; 46 47 48 / <summary> 49
28、0; / Sinpson法則求積分 50 / 積分公式為:(b - a) / 6) * f(a) + 4 * f(a + b) / 2) + f(b) 51 / </summary> 52 / <param name="a">積分下限<
29、;/param> 53 / <param name="b">積分上限</param> 54 / <returns>積分值</returns> 55 public static double SinpsonIntegrate(double a,
30、double b) 56 57 return (b - a) / 6) * (Math.Sin(a) / a + 4 * (Math.Sin(a + b) / (2 * (a + b) + Math.Sin(b) / b); 58 59
31、60;60 / <summary> 61 / 復(fù)化Sinpson法則求積分 62 / 積分公式為:累加(h / 3) * f(x2i-2) + 4*(f(x2i-1) + f(x2i) (i=1,2,.,n/2 h = (b - a) / n) 63
32、0; / </summary> 64 / <param name="a">積分下限</param> 65 / <param name="b">積分上限</param> 66
33、;/ <param name="n">分段數(shù)量(必須為偶數(shù))</param> 67 / <returns>積分值</returns> 68 public static double ComplexSinpsonIntegrate(double a, double b, int n) 69
34、0; 70 double result = 0; 71 for (int i = 0; i < n / 2 - 1; i+) 72
35、 73 double xa = a + 2 * i * (b - a) / n;/區(qū)間積分下限 74 double xb = xa + (b - a) / n;/區(qū)間積分限中點(diǎn) 75 &
36、#160; double xc = xb + (b - a) / n;/區(qū)間積分上限 76 result += (b - a) / (3 * n) * (Math.Sin(xa) / xa + 4 * (Math.Sin(xb) / xb) + Math.Sin(xc
37、) / xc); 77 78 79 return result; 80 81 822、Monte-Carlo積分法
38、; 我們知道,求定積分的直觀意義就是求面積,所以,用Monte-Carlo求積分的原理就是通過(guò)模擬統(tǒng)計(jì)方法求解面積。即通過(guò)向特定區(qū)域隨機(jī)產(chǎn)生大量點(diǎn),然后統(tǒng)計(jì)點(diǎn)落在函數(shù)區(qū)域內(nèi)的頻率,以此頻率估計(jì)面積,從而得到積分值。下面給出Monte-Carlo求取積分的算法程序。view source print?01using System; 02using System.Collections.Generic; 03using System.Linq; 04using System.Text; 05 06namespace MonteC
39、arlo.Integration 07 08 / <summary> 09 / Monte-Carlo法求積分 10 / 被積函數(shù)為 f(x) = (sin x)/x 11 / </summary> 12 public class MonteCarloIntegrator 13 14 &
40、#160; / <summary> 15 / 用Monte-Carlo法求解積分值 16 / </summary> 17 / <param name="a">積分下限</param>
41、; 18 / <param name="b">積分上限</param> 19 / <param name="N">模擬次數(shù)</param> 20 / <returns>積分值</returns> 21
42、60; public static double MonteCarloIntegrate(int a, int b, int N) 22 23 Random random = new Random(); 24
43、 int positivePointCount = 0;/y >=0 區(qū)間內(nèi)落入函數(shù)曲線內(nèi)的點(diǎn)數(shù)目 25 int negativePointCount = 0;/y < 0區(qū)間內(nèi)落入函數(shù)曲線內(nèi)的點(diǎn)數(shù)目 26 27
44、; /統(tǒng)計(jì)y >= 0區(qū)間點(diǎn)分布 28 for (int i = 0; i < N; i+) 29 30
45、0;double xCoordinate = random.NextDouble();/隨機(jī)產(chǎn)生的x坐標(biāo) 31 double yCoordinate = random.NextDouble();/隨機(jī)產(chǎn)生的y坐標(biāo) 32
46、xCoordinate = a + (b - a) * xCoordinate;/將x規(guī)格化到相應(yīng)積分區(qū)間 33 /yCoordinate = 1 * yCoordinate;/將y規(guī)格化到相應(yīng)區(qū)間 34 if (Mat
47、h.Sin(xCoordinate) / xCoordinate >= yCoordinate) 35 36 positivePointCount+; 37
48、0; 38 39 40 /統(tǒng)計(jì)y < 0區(qū)間點(diǎn)分布 41 &
49、#160; for (int i = 0; i < N; i+) 42 43 double xCoordinate = random.NextDouble();/隨機(jī)
50、產(chǎn)生的x坐標(biāo) 44 double yCoordinate = random.NextDouble();/隨機(jī)產(chǎn)生的y坐標(biāo) 45 xCoordinate = a + (b - a) * xCoordinate;/將x規(guī)格化
51、到相應(yīng)積分區(qū)間 46 yCoordinate = -1 * yCoordinate;/將y規(guī)格化到相應(yīng)區(qū)間 47 if (Math.Sin(xCoordinate) / xCoordinate <= yCoordi
52、nate) 48 49 negativePointCount+; 50
53、160; 51 52 53 double positiveFrequency = (double)positivePointCount / (double)N;/y >= 0區(qū)間內(nèi)函數(shù)內(nèi)點(diǎn)頻
54、率 54 double negativeFrequency = (double)negativePointCount / (double)N;/y < 0區(qū)間內(nèi)函數(shù)內(nèi)點(diǎn)頻率 55 56 return (positiveFrequency - negativeFrequency
55、) * (double)(b - a); 57 58 593、積分法的測(cè)試與比較 下面對(duì)各種積分方法進(jìn)行測(cè)試,對(duì)sinx/x在1,2區(qū)間上進(jìn)行定積分。其中,我們分別對(duì)復(fù)化梯形和復(fù)化Sinpson法則做分段為10,10000,和10000000的積分測(cè)試。另外,對(duì)Monte-Carlo法也投點(diǎn)數(shù)也分為10,10000,和10000000。測(cè)試結(jié)果如下:圖3、積分法測(cè)試結(jié)果
56、 為了分析偏差,我們必須給出一個(gè)精確值。但是現(xiàn)在我手頭沒(méi)有這個(gè)積分的精確值,不過(guò)1000萬(wàn)次的梯形法則和Sinpson法則已經(jīng)精確度很高了,所以這里就以0.65932985作為基本,進(jìn)行誤差分析。下面給出分析結(jié)果:表1、積分方法實(shí)驗(yàn)結(jié)果 首先看時(shí)間效率。當(dāng)頻度較低時(shí),各種方法沒(méi)有太多差別,但在1000萬(wàn)級(jí)別上復(fù)化梯形和復(fù)化Sinpson相差不大,而Monte-Carlo算法的效率快一倍。 而從準(zhǔn)確率分析,當(dāng)頻度較低時(shí),幾種方法的誤差都很大,
57、而隨著頻度提高,插值法要遠(yuǎn)遠(yuǎn)優(yōu)于Monte-Carlo算法,特別在1000萬(wàn)級(jí)別時(shí),Monte-Carlo法的相對(duì)誤差是插值法的的近萬(wàn)倍??傮w來(lái)說(shuō),在數(shù)值積分方面,Monte-Carlo方法效率高,但準(zhǔn)確率不如插值法。應(yīng)用實(shí)例二:在O(n)復(fù)雜度內(nèi)判定主元素 這次,我們看一個(gè)判定問(wèn)題。問(wèn)題是這樣的:在一個(gè)長(zhǎng)度為n的數(shù)組中,如果有超過(guò)n/2的元素具有相同的值,那么具有這個(gè)值的元素叫做數(shù)組的主元素?,F(xiàn)在要求給出一種算法,在O(n)時(shí)間內(nèi)判定給定數(shù)組是否存在主元素。 如果采用確定性
58、算法,由于最壞情況下要搜索n/2次,而每次要比較的次數(shù)為O(n)量級(jí),這樣,算法的復(fù)雜度就是O(n2),不可能在O(n)時(shí)間內(nèi)完成。所以我們只好換一種思路:不是要一個(gè)一定正確的結(jié)果,而只需要結(jié)果在很大概率上正確就行。我們可以這樣做:圖4、Monte-Carlo法判定主元素 上述算法,就是用Monte-Carlo思想求解主元素判定問(wèn)題的過(guò)程。由于閾值N是一個(gè)給定的常數(shù),不隨規(guī)模變化而變化,所以這個(gè)算法的時(shí)間復(fù)雜度為O(n),符合題設(shè)要求。但這個(gè)算法給出的解并不是100%正確的,正確率和N有關(guān)。N設(shè)得過(guò)大,影響效率,N太小,正確率太低,那
59、么到底N設(shè)多大合適呢。這就要對(duì)算法進(jìn)行概率分析。 首先,這個(gè)算法是一致且偏真的,證明很簡(jiǎn)單,這里從略。所以,如果數(shù)組中不存在主元素,則結(jié)果一定正確,而如果存在,調(diào)用一次得到正確結(jié)果的概率不低于1/2。由于偏真,在N次調(diào)用中只要返回一次True,就可以認(rèn)為得到正確結(jié)果,所以,調(diào)用N此得到正確結(jié)果的概率不低于1 (1/2)N,可以看到,隨著N的增大,這個(gè)概率增加很快,只要調(diào)用10次,正確率就可以達(dá)到99.9%,重要的是,這個(gè)正確率和規(guī)模無(wú)關(guān),即使數(shù)組的元素有1千萬(wàn)億,只需調(diào)用10次,正確率依然是99.9%,這就體現(xiàn)出在數(shù)組很大時(shí),Mont
60、e-Carlo方法的優(yōu)勢(shì)。 下面是使用Monte-Carlo算法進(jìn)行主元素測(cè)試的C#程序示例。view source print?01using System; 02using System.Collections.Generic; 03using System.Linq; 04using System.Text; 05 06namespace MonteCarlo.Detection 07 08 public class PrincipalElement
61、Detector 09 10 / <summary> 11 / 使用Monte-Carlo發(fā)探測(cè)主元素 12 / </summary> 13 / <
62、;param name="elements">所有元素</param> 14 / <param name="N">閾值</param> 15 / <returns>是否存在主元素</returns> 16 pub
63、lic static bool DetectPrincipalElement(IList<int> elements,int N) 17 18 Random random = new Random(); 19
64、;bool result = false; 20 for (int i = 0; i <= N; i+) 21 22
65、int index = random.Next(0, elements.Count - 1); 23 int element = elementsindex; 24 int count = 0; 25
66、0; for (int j = 0; j < elements.Count; j+) 26 27
67、0; if (element = elementsj) 28 29
68、0; count+; 30 31 32
69、 if (count >= elements.Count / 2) 33 34 &
70、#160; result = true; 35 break; 36 37
71、160; 38 39 return result; 40 41 42 程序很簡(jiǎn)單,不做贅述。下面測(cè)試這個(gè)算法。我們分別將閾值設(shè)為1、3、10,并且
72、在每個(gè)閾值下測(cè)試100次,看看這個(gè)算法的準(zhǔn)確率如何。測(cè)試數(shù)組是 4, 5, 8, 1, 8, 4, 9, 2, 2, 2, 2, 2, 5, 7, 8, 2, 2, 2, 2, 2, 1, 0, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 4, 7, 8, 2, 2, 2, 2, 2, 0, 1, 2, 2, 2, 2, 2 ,其中存在主元素2。下面是測(cè)試結(jié)果:圖5、Monte-Carlo算法判定主元素實(shí)驗(yàn)結(jié)果 測(cè)試數(shù)組有49個(gè)元素,主元素2有29個(gè),比率為59%。從測(cè)試結(jié)果可以看出,即使閾值為1,正確率也
73、高達(dá)84%,而僅僅為3的閾值就使正確率升高到98%,閾值為10時(shí),100次測(cè)試全部正確。雖然理論上來(lái)說(shuō),閾值為10時(shí)有0.4110=0.013%的概率給出錯(cuò)誤判斷,但是筆者多次試驗(yàn),還沒(méi)有在閾值為10時(shí)得到錯(cuò)誤結(jié)果。所以,Monte-Carlo方法求解判定問(wèn)題,不論從理論上還是實(shí)踐中,都是不錯(cuò)的方法。 另外一個(gè)與判定主元素類似的應(yīng)用是素?cái)?shù)判定問(wèn)題,我們知道,對(duì)于尋找上百位的大素?cái)?shù),完全測(cè)試在時(shí)間效率上時(shí)不允許的。于是,結(jié)合費(fèi)馬小定理使用Monte-Carlo法進(jìn)行素?cái)?shù)判定,是廣泛使用的方法。具體這里不再詳述,感興趣的朋友可以參考相關(guān)資
74、料。應(yīng)用實(shí)例三:分布未知的概率密度函數(shù)模擬 現(xiàn)在我們來(lái)看看Monte-Carlo算法的第三種應(yīng)用:模擬。在這種應(yīng)用中,不再是用Monte-Carlo算法求解問(wèn)題,而是用來(lái)模擬難以解析描述的東西。問(wèn)題是這樣的: 這個(gè)問(wèn)題是實(shí)驗(yàn)室一個(gè)師兄在開(kāi)發(fā)Six Sigma軟件開(kāi)發(fā)過(guò)程管理工具時(shí)遇到的一個(gè)實(shí)際需求,最終Y的概率密度函數(shù)將被用來(lái)計(jì)算分位點(diǎn),從而進(jìn)行過(guò)程控制。其中X可能是正態(tài)分布(高斯分布)、泊松分布、均勻分布或指數(shù)分布等。將多個(gè)不同分布的概率密度函數(shù)相加,得到的Y的分布式很難解
75、析表示出來(lái)的,但如果是為了計(jì)算分位點(diǎn),我們可以采取這樣一個(gè)策略:對(duì)于每一個(gè)X,產(chǎn)生若干符合其分布的點(diǎn),帶入公式就得到若干符合Y分布的點(diǎn),然后分段計(jì)算頻率,從而模擬出Y的分布,這些模擬點(diǎn)也可以用于分位點(diǎn)計(jì)算。這就是Monte-Carlo模擬的思想。 下面我們實(shí)現(xiàn)這個(gè)算法,這里的X我們僅給出最常用的正態(tài)分布,如果要實(shí)現(xiàn)其他分布,只要編寫(xiě)相應(yīng)的隨機(jī)點(diǎn)發(fā)生器就可以了。由于C#中只能產(chǎn)生符合均勻分布的隨機(jī)數(shù),所以我們需要一種算法,將均勻分布的隨機(jī)數(shù)轉(zhuǎn)為正態(tài)分布隨機(jī)數(shù)。這種算法很多,Marc Brysbaert在1991年發(fā)表的Algorithm
76、s for randomness in the behavioral sciences: A tutorial一文中,共總結(jié)了5種將均勻分布隨機(jī)數(shù)轉(zhuǎn)為正態(tài)分布的隨機(jī)數(shù)的算法,這里筆者用到的是Knuth在1981年提出的一種算法。這個(gè)算法是將符合u(0,1)均勻分布的隨機(jī)點(diǎn)轉(zhuǎn)換為符合N(0,1)標(biāo)準(zhǔn)正態(tài)分布的隨機(jī)點(diǎn)p,由概率知識(shí)可知,要轉(zhuǎn)為符合N(e,v)的一般正態(tài)分布,只需進(jìn)行p*v+e即可。下面是這個(gè)算法: 下面是根據(jù)這個(gè)算法,使用C#編寫(xiě)的正態(tài)分布隨機(jī)點(diǎn)發(fā)生器:view source print?01using System; 0
77、2using System.Collections.Generic; 03using System.Linq; 04using System.Text; 05 06namespace MonteCarlo.DistributingSimulation 07 08 public class NormalDistributingGenerator 09 10 / <summ
78、ary> 11 / 產(chǎn)生符合正態(tài)分布的隨機(jī)數(shù) 12 / 正態(tài)分布的期望為expectation,方差為variance 13 / </summary> 14 / <param name="e
79、xpectation">期望</param> 15 / <param name="variance">方差</param> 16 / <param name="N">產(chǎn)生的數(shù)量</param> 17 /
80、 <returns>隨機(jī)數(shù)序列</returns> 18 public static IList<double> GenerateNDRNumber(double expectation, double variance, int N) 19 20
81、60; Random random = new Random(); 21 IList<double> randomList = new List<double>(); 22 for (int i = 0; i < N; i+) 23
82、0; 24 double u1, u2, v, z, a; 25 do26 &
83、#160; 27 u1 = random.NextDouble(); 28
84、 u2 = random.NextDouble(); 29 v = 0.8578 * (2 * u2 - 1); 30
85、60; z = v / u1; 31 a = 0.25 * Math.Exp(2); 32 33
86、60; if (a < 1 - u1) 34 35
87、60; break; 36 37 38 while (a > 0.295 / u1
88、 + 0.35 | a > -Math.Log(u1, Math.E); 39 40 randomList.Add(z * Math.Sqrt(variance) + expectation); 41 42
89、0; 43 return randomList; 44 45 46 接著是利用這個(gè)正態(tài)分布發(fā)生器獲得X的隨機(jī)值,并計(jì)算出Y的隨機(jī)值的代碼。也就是Y的隨機(jī)點(diǎn)發(fā)生器:view source print?01using System; 02using Syst
90、em.Collections.Generic; 03using System.Linq; 04using System.Text; 05 06namespace MonteCarlo.DistributingSimulation 07 08 public class DistributingSimulator 09 10 / <summary> 11 &
91、#160; / 模擬多個(gè)正態(tài)分布之和的分布情況,產(chǎn)生符合復(fù)合分布的隨機(jī)點(diǎn) 12 / y = a0 + a1*N(e1,v1) + . + an*N(en,vn) 13 / N(e,v)表示期望為e,方差為v的正態(tài)分布 14 / </summa
92、ry> 15 / <param name="a">常數(shù)列</param> 16 / <param name="e">期望列</param> 17 / <param name="v">方差列&l
93、t;/param> 18 / <param name="N">產(chǎn)生模擬點(diǎn)的個(gè)數(shù)</param> 19 / <returns>模擬點(diǎn)序列</returns> 20 public static IList<double> Simulate(IList<double> a,IList<double> e,IList<double> v,int N) 21 22
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年CDMA第三代蜂窩移動(dòng)通信系統(tǒng)合作協(xié)議書(shū)
- 兩萬(wàn)合同范本
- 司法拍賣(mài)土地合同范本
- 修補(bǔ)圍網(wǎng)合同范例
- 政府委托代建合同范本
- 合影攝影合同范本
- 立法調(diào)研專項(xiàng)委托合同范本
- 宜城市個(gè)人攤位出租合同范本
- 債券質(zhì)押貸款合同范本
- 合同范本模板購(gòu)買(mǎi)
- 成功人士的七個(gè)習(xí)慣課件
- 粵教版必修二《向心力》評(píng)課稿
- 中國(guó)建筑史PPT(東南大學(xué))完整全套教學(xué)課件
- 2022年水利監(jiān)理規(guī)劃
- 哈弗汽車(chē)品牌全案策略及營(yíng)銷推廣方案
- 04J008 擋土墻(重力式 衡重式 懸臂式)
- (學(xué)校教育論文)人工智能下的教育變革研究
- 2023年湖南工程職業(yè)技術(shù)學(xué)院?jiǎn)握泄P試職業(yè)技能考試題庫(kù)及答案解析
- 春天的氣息-教學(xué)設(shè)計(jì)教案
- NB/T 10740-2021露天煤礦大型卡車(chē)運(yùn)行日常安全檢查規(guī)程
- GB/T 41855-2022小型游樂(lè)設(shè)施轉(zhuǎn)椅
評(píng)論
0/150
提交評(píng)論