0042演算法筆記——【隨機化演算法】計算π值和計算定積分
阿新 • • 發佈:2019-02-08
1、計算π值
問題描述
設有一半徑為r的圓及其外切四邊形。向該正方形隨機地投擲n個點。設落入圓內的點數為k。由於所投入的點在正方形上均勻分佈,因而所投入的點落入圓內的概率為 。所以當n足夠大時,k與n之比就逼近這一概率。從而。
程式具體程式碼如下:
程式執行結果如圖://隨機化演算法 用隨機投點法計算π值 #include "stdafx.h" #include "RandomNumber.h" #include <iostream> using namespace std; double Darts(int n); int main() { int n1 = 100,n2 = 1000,n3 = 1000,n4 = 10000,n5 = 10000000; cout<<"n1="<<n1<<",π1="<<Darts(n1)<<endl; cout<<"n2="<<n2<<",π2="<<Darts(n2)<<endl; cout<<"n3="<<n3<<",π3="<<Darts(n3)<<endl; cout<<"n4="<<n4<<",π4="<<Darts(n4)<<endl; cout<<"n5="<<n5<<",π5="<<Darts(n5)<<endl; return 0; } //用隨機投點法計算π值 double Darts(int n) { static RandomNumber dart; int k = 0; for(int i=1; i<=n; i++) { double x = dart.fRandom(); double y = dart.fRandom(); if((x*x + y*y)<=1) { k++; } } return 4*k/double(n); }
2、計算定積分
例:設f(x)=x^2,求
解:
1)隨機投點法計算定積分
基本思想是在矩形區域上隨機均勻的投點實現。本演算法的基本思想是在積分割槽間上隨機均勻的產生點, 即在[a,b]上隨機均勻的取點, 求出由這些點產生的函式值的算術平均值, 再乘以區間寬度, 即可解出定積分得近似解。
演算法具體程式碼如下:
程式執行結果如圖://隨機化演算法 用隨機投點法計算定積分 #include "stdafx.h" #include "RandomNumber.h" #include <iostream> using namespace std; double Darts(int n,double a,double b); double f(double x); int main() { int n1 = 100,n2 = 1000,n3 = 1000,n4 = 10000,n5 = 10000000; double a = 2.0,b = 3.0; cout<<"n1="<<n1<<",r1="<<Darts(n1,a,b)<<endl; cout<<"n2="<<n2<<",r2="<<Darts(n2,a,b)<<endl; cout<<"n3="<<n3<<",r3="<<Darts(n3,a,b)<<endl; cout<<"n4="<<n4<<",r4="<<Darts(n4,a,b)<<endl; cout<<"n5="<<n5<<",r5="<<Darts(n5,a,b)<<endl; return 0; } /* * 基本思想是在矩形區域內隨機均勻投點,求出由這些點 * 產生的函式值的算術平均值,再乘以區間寬度,即可得 * 出定積分的近似解 */ double Darts(int n,double a,double b) { static RandomNumber dart; double sum = 0.0; for(int i=0; i<n; i++) { double x = (b-a)*dart.fRandom() + a;//產生[a,b)之間的隨機數 sum = sum + f(x); } return (b-a)*sum/n; } double f(double x) { return x*x; }
2)概率法法計算定積分
設f:[a,b]→[c,d]連續函式(如圖2 所示), 則由曲線y=f(x)以及x 軸和直線x=a,x=b 圍成的面積由定積分給出。根據幾何概型可知。假設向矩形區域隨機均勻的投鏢n 次, 落入陰影為K次, 又設M為x=a、x=b、y=c、y=d 所圍成的矩形面積, s 為定積分面積,則, 所以s= k/n×M。
演算法具體程式碼 如下:
程式執行結果如圖://隨機化演算法 用概率法計算定積分 #include "stdafx.h" #include "RandomNumber.h" #include <iostream> using namespace std; double Darts(int n,double a,double b,double d); double f(double x); int main() { int n1 = 100,n2 = 1000,n3 = 1000,n4 = 10000,n5 = 10000000; double a = 2.0,b = 3.0; double d = f(b); cout<<"n1="<<n1<<",r1="<<Darts(n1,a,b,d)<<endl; cout<<"n2="<<n2<<",r2="<<Darts(n2,a,b,d)<<endl; cout<<"n3="<<n3<<",r3="<<Darts(n3,a,b,d)<<endl; cout<<"n4="<<n4<<",r4="<<Darts(n4,a,b,d)<<endl; cout<<"n5="<<n5<<",r5="<<Darts(n5,a,b,d)<<endl; return 0; } /* * f 為積分函式, n 為投鏢 * 總數, a,b 為積分割槽間, c,d 為函 * 數f 的值域的端點值 */ double Darts(int n,double a,double b,double d) { static RandomNumber dart; int k = 0; for(int i=0; i<n; i++) { double x = (b-a)*dart.fRandom() + a;//產生[a,b)之間的隨機數 double y = d * dart.fRandom(); if(y<=f(x)) { k++; } } return d*(b-a)*k/n; } double f(double x) { return x*x; }