這次我們來介紹一下求pi值的第二種方法,概率法,也叫蒙特卡洛方法。
這個程式的原理十分簡單,如下圖。
然後我們可以發現,其實我們想要的答案已經顯而易見了。如果是序列的程式,似乎也沒什麼好說的。隨機生成n個x座標y座標均小於1的點。然後統計具體有多少個點落在圓弧範圍內即可。
但聰明如我發現了事情不會這麼簡單
經大佬提醒,我發現這樣子實現並行程式的速度極慢,甚至是不像乙個並行程式,因此我們來**一下事情可能發生在**。
沒錯,思來想去,也就只有rand函式可能出了一些問題,那麼讓我們來看看rand()函式的本質是什麼吧!
rand()函式產生隨機數,但是,其內部實現是用線性同餘法實現的,是偽隨機數,由於週期較長,因此在一定範圍內可以看成是隨機的。
rand()會返回乙個範圍在0到rand_max(至少是32767)之間的偽隨機數(整數)。
在呼叫rand()函式之前,可以使用srand()函式設定隨機數種子,如果沒有設定隨機數種子,rand()函式在呼叫時,自動設計隨機數種子為1。隨機種子相同,每次產生的隨機數也會相同。
rand函式在產生隨機數前,需要系統提供的生成偽隨機數序列的種子,rand根據這個種子的值產生一系列隨機數。如果系統提供的種子沒有變化,每次呼叫rand函式生成的偽隨機數序列都是一樣的。
經過仔細的分析,我們發現了乙個名詞,種子!
q:什麼是種子呢
a:是snis,哦不,是ipz ,哦不不不,其實是這個——seed。
因此,我們知道了,rand()函式其實是執行緒不安全的,會導致種子競爭,因此並行性並不好。
那麼我們要怎麼辦呢?
經過一番搜尋,我們發現了函式——rand_r()。
/* this algorithm is mentioned in the iso c standard, here extended
for 32 bits. */
intrand_r (unsigned int *seed)
這樣的乙個函式代表什麼呢?
它代表我們可以編寫真正的並行程式了!
gogogogo!
void *thread_function(void *arg)
}pthread_mutex_lock
(&mut)
; pi =
(pi + demo)
;pthread_mutex_unlock
(&mut)
;return
null;}
intmain
(int argc,
const
char
* ar**)
for(
int i=
0;i) pi =
4*pi/n;
cout<<
setprecision(8
)<
return0;
}
在下還很菜,還請諸位多多指教,一起進步。 蒙特卡洛法
蒙特卡洛 monte carlo 方法,或稱計算機隨機模擬方法,是一種基於 隨機數 的計算方法。這一方法源於 美國在第二次世界大戰進研製原子彈的 曼哈頓計畫 該計畫的 主持人之 一 數學家馮 諾伊曼用馳名世界的賭城 摩納哥的monte carlo 來命名這種方法,為它蒙上了一層神秘色彩。monte ...
民科解釋蒙特卡洛法
蒙特卡羅方法於20世紀40年代美國在第二次世界大戰中研製原子彈的 曼哈頓計畫 計畫的成員s.m.烏拉姆和j.馮 諾伊曼首先提出。數學家馮 諾伊曼用馳名世界的賭城 摩納哥的monte carlo 來命名這種方法,為它蒙上了一層神秘色彩。先看看wiki的解釋 蒙特卡羅方法 英語 monte carlo ...
蒙特卡洛法求圓周率
利用蒙特卡洛演算法求圓周率是乙個概率的方法,關於這方面的內容很多,而且也很容易理解,更多具體分析過程可以參考如下文章 下面是我的理解和 蒙特卡洛演算法是通過概率來計算pi的值的。對於乙個單位為1的正方形,以其某乙個頂點為圓心,邊為半徑在正方形內畫扇形 乙個1 4的圓形的扇形 那麼扇形的面積就是pi ...