0042算法笔记——【随机化算法】计算π值和计算定积分

来源:互联网 发布:nao机器人编程 编辑:程序博客网 时间:2024/06/05 05:33

     1、计算π值

    问题描述

    设有一半径为r的圆及其外切四边形。向该正方形随机地投掷n个点。设落入圆内的点数为k。由于所投入的点在正方形上均匀分布,因而所投入的点落入圆内的概率为           。所以当n足够大时,k与n之比就逼近这一概率。从而


    程序具体代码如下:

[cpp] view plaincopyprint?
  1. //随机化算法 用随机投点法计算π值   
  2. #include "stdafx.h"   
  3. #include "RandomNumber.h"  
  4. #include <iostream>   
  5. using namespace std;  
  6.   
  7. double Darts(int n);  
  8.   
  9. int main()  
  10. {  
  11.     int n1 = 100,n2 = 1000,n3 = 1000,n4 = 10000,n5 = 10000000;  
  12.     cout<<"n1="<<n1<<",π1="<<Darts(n1)<<endl;  
  13.     cout<<"n2="<<n2<<",π2="<<Darts(n2)<<endl;  
  14.     cout<<"n3="<<n3<<",π3="<<Darts(n3)<<endl;  
  15.     cout<<"n4="<<n4<<",π4="<<Darts(n4)<<endl;  
  16.     cout<<"n5="<<n5<<",π5="<<Darts(n5)<<endl;  
  17.     return 0;  
  18. }  
  19.   
  20. //用随机投点法计算π值   
  21. double Darts(int n)  
  22. {  
  23.     static RandomNumber dart;  
  24.     int k = 0;  
  25.   
  26.     for(int i=1; i<=n; i++)  
  27.     {  
  28.         double x = dart.fRandom();  
  29.         double y = dart.fRandom();  
  30.         if((x*x + y*y)<=1)  
  31.         {  
  32.             k++;  
  33.         }  
  34.     }  
  35.   
  36.     return 4*k/double(n);  
  37. }  
//随机化算法 用随机投点法计算π值#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]上随机均匀的取点, 求出由这些点产生的函数值的算术平均值, 再乘以区间宽度, 即可解出定积分得近似解


    算法具体代码如下:

[cpp] view plaincopyprint?
  1. //随机化算法 用随机投点法计算定积分   
  2. #include "stdafx.h"   
  3. #include "RandomNumber.h"  
  4. #include <iostream>   
  5. using namespace std;  
  6.   
  7. double Darts(int n,double a,double b);  
  8. double f(double x);  
  9.   
  10. int main()  
  11. {  
  12.     int n1 = 100,n2 = 1000,n3 = 1000,n4 = 10000,n5 = 10000000;  
  13.     double a = 2.0,b = 3.0;  
  14.     cout<<"n1="<<n1<<",r1="<<Darts(n1,a,b)<<endl;  
  15.     cout<<"n2="<<n2<<",r2="<<Darts(n2,a,b)<<endl;  
  16.     cout<<"n3="<<n3<<",r3="<<Darts(n3,a,b)<<endl;  
  17.     cout<<"n4="<<n4<<",r4="<<Darts(n4,a,b)<<endl;  
  18.     cout<<"n5="<<n5<<",r5="<<Darts(n5,a,b)<<endl;  
  19.     return 0;  
  20. }  
  21.   
  22. /* 
  23.  * 基本思想是在矩形区域内随机均匀投点,求出由这些点 
  24.  * 产生的函数值的算术平均值,再乘以区间宽度,即可得 
  25.  * 出定积分的近似解 
  26.  */  
  27. double Darts(int n,double a,double b)  
  28. {  
  29.     static RandomNumber dart;  
  30.     double sum = 0.0;  
  31.     for(int i=0; i<n; i++)  
  32.     {  
  33.         double x = (b-a)*dart.fRandom() + a;//产生[a,b)之间的随机数  
  34.         sum = sum + f(x);  
  35.     }  
  36.     return (b-a)*sum/n;  
  37. }  
  38.   
  39. double f(double x)  
  40. {  
  41.     return x*x;  
  42. }  
//随机化算法 用随机投点法计算定积分#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。


    算法具体代码 如下:

[cpp] view plaincopyprint?
  1. //随机化算法 用概率法计算定积分   
  2. #include "stdafx.h"   
  3. #include "RandomNumber.h"  
  4. #include <iostream>   
  5. using namespace std;  
  6.   
  7. double Darts(int n,double a,double b,double d);  
  8. double f(double x);  
  9.   
  10. int main()  
  11. {  
  12.     int n1 = 100,n2 = 1000,n3 = 1000,n4 = 10000,n5 = 10000000;  
  13.     double a = 2.0,b = 3.0;  
  14.     double d = f(b);  
  15.     cout<<"n1="<<n1<<",r1="<<Darts(n1,a,b,d)<<endl;  
  16.     cout<<"n2="<<n2<<",r2="<<Darts(n2,a,b,d)<<endl;  
  17.     cout<<"n3="<<n3<<",r3="<<Darts(n3,a,b,d)<<endl;  
  18.     cout<<"n4="<<n4<<",r4="<<Darts(n4,a,b,d)<<endl;  
  19.     cout<<"n5="<<n5<<",r5="<<Darts(n5,a,b,d)<<endl;  
  20.     return 0;  
  21. }  
  22.   
  23. /* 
  24.  * f 为积分函数, n 为投镖 
  25.  * 总数, a,b 为积分区间, c,d 为函 
  26.  * 数f 的值域的端点值 
  27.  */  
  28. double Darts(int n,double a,double b,double d)  
  29. {  
  30.     static RandomNumber dart;  
  31.     int k = 0;  
  32.     for(int i=0; i<n; i++)  
  33.     {  
  34.         double x = (b-a)*dart.fRandom() + a;//产生[a,b)之间的随机数  
  35.         double y = d * dart.fRandom();  
  36.   
  37.         if(y<=f(x))  
  38.         {  
  39.             k++;  
  40.         }  
  41.     }  
  42.     return d*(b-a)*k/n;  
  43. }  
  44.   
  45. double f(double x)  
  46. {  
  47.     return x*x;  
  48. }  
//随机化算法 用概率法计算定积分#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;}
    程序运行结果如图:


  

原创粉丝点击