电脑的特点在于速度快,记忆好,最擅长做机械化的重复工作,用暴力的方法来近似pi值可以利用蒙特卡洛方法或微分法来计算。
1 蒙特卡洛方法和微分法求π值
如上图所示:
对于单元圆的面积:πr^2=π(单位圆的半径为1)
正方形的面积:1
1/4单元圆与正方形的面积的比值=4/π
如果随机产生一个0-1内的数,其落在1/4单元圆内的概率与落在正方形内的概率就是两个图形的面积之比,随机数越多,越真实接近。
落在正方形内的随机数个数可以用总的随机数的个数来表示。
其落在单元圆内的随机数个数可以通过计算其坐标点与圆点的距离比较而求得,如果<=1则表示位于单位圆内。
#include <iostream> using namespace std; #include <math.h> #include<time.h> void main() { int p; //随机数 int circle; //圆内的点 int square; //正方形内的点 int toss; //投掷次数 int rm=RAND_MAX;//最大随机数 float pi; //pi值 float x,y; //坐标值 float r; //点与原点的距离 char flag; srand((unsigned)time(NULL)); do{ circle=0; do{ cout<<"Enter the number of tosses(2<=N<=55555):"; cin>>toss; }while((toss<2) || (toss>55555)); square = toss; for(int i=0;i<toss;++i) { p=rand(); x=((float)p)/rm; p=rand(); y=((float)p)/rm; r=sqrt((x*x)+(y*y)); if(r<=1) ++circle; } pi=4*((float)circle)/square; cout<<"The value of pi is:"<<pi<<endl; cout<<"do you want to continue?(y/n):"; cin>>flag; }while((flag=='y') || (flag=='Y')); system("pause"); } //#include <stdio.h> //#include <stdlib.h> //cin.ignore
运行结果:
2 微分法求PI值
定积分的物理意义是某个函数与x轴围成的区域的面积。定积分可以通过将这块面积分解成一连串的小矩形,计算各小矩形的面积的和而得到,如图下图所示,曲线函数f(x)=x^2+5x+1,小矩形的宽度可由用户指定,高度就是对应于这个x的函数值f(x)。区间[a, b]的a、b及小矩形的宽度在程序执行时由用户输入。
如果小矩形的宽度是delt,起点坐标是x,则矩形的近似面积为delt*f(x+delt/2)。
计算定积分只需要沿着x轴将一个个小矩形的面积相加即可。
用类似的方法可以求π 的近似值,具体思想如下:
在平面坐标系中有一个圆心在原点,半径为1的圆,用矩形法计算第一象限的面积S,4 * S就是整个圆的面积。圆面积也可以通过π*r^2来求,因此可得π = 4 * S。尝试不同的小矩形宽度,以得到不同精度的π 值。
在第一象限中,x的值从0变到1。圆上的每个点的坐标为(x, sqrt(1-x^2 )。如果矩形的宽度为delt,计算第一象限中的圆面积就是沿着x轴,从delt/2到1计算每个小矩形面积并相加。
#include <iostream> #include <cmath> using namespace std; int main() { double x, s = 0, delt; cout << "请输入小矩形的宽度: "; cin >> delt; for ( x = delt / 2; x <= 1; x += delt) // 计算第一象限内的圆面积 s += sqrt(1 - x * x) * delt; cout << "π 的近似值是:" << 4 * s << endl; cin.get();cin.get(); return 0; } /* 请输入小矩形的宽度: 0.01 π 的近似值是:3.14194 */
-End-