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);
- }
//随机化算法 用随机投点法计算π值
#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;
- }
//随机化算法 用随机投点法计算定积分
#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;
- }
//随机化算法 用概率法计算定积分
#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;
}
程序运行结果如图: