我们从小学的时候就已经熟知了π的值是介于3.1415926到3.1415927之间的一个无限不循环小数,今天我们就来利用java中的Math.random()这个随机数产生器来计算π的值,产生的数值范围为0~1。
用随机数来计算π的值可能大家有些迷惑。
那我们首先来看下这个问题,现在我手里面有一把均匀的黄豆,我把它们撒在如下图所示的图形里面
撒前 撒后
现在我们就需要知道我每一次撒的豆子落在中间这个小矩形里面的概率是多少?
我们可以直观的看出这是一个几何概率问题,我们只需知道大矩形的面积和小矩形的面积就可以计算出其概率。
那么我们计算π的值是否也可以借此方法呢?比如我们有如下所示的图
在该矩形中有一个圆,我们也效仿刚刚撒豆的方法,如下图
那么其几何概率就应该为圆的面积除以矩形的面积,则计算出了其几何概率。
那又如何与我们java中的随机数联系起来呢?
我们不妨将上面的图形放入二维直角坐标系中
我们用两个随机数x,y来代表一颗豆子在该坐标系中的位置,由于Math.random()产生的随机数是0~1的,所以这里我们设该矩形的边长为1的正方形,设圆的半径为0.3,圆心坐标为(0.5,0.5),则我们就可以使用距离公式d^2=(x-0.5)^2+(y-0.5)^2,即d<=0.09来判断一颗豆子是否在圆内和圆上,然后我们用一个for循环来模拟撒的一把豆子,然后算出本次撒在圆中的概率值P。又因为P=πr^2/矩形面积即P=π*0.09/1,则π=100P/9,然后我们在前面的那个for循环外面再套一个for循环用来作为我撒豆的次数,把所有的次数得到的结果求一个平均值则为求得的π值。
代码如下
public class PI {
public static void main(String []args){
double x=0;
double y=0;
double sum=0;
double avge=0;
for(double j=0;j<9000;j++)//循环1为总共撒豆次数
{
for(int i=0;i<9000;i++){//循环2执行完为一次撒豆,及豆子的数量
//每一个豆子的坐标
x=Math.random();
y=Math.random();
if(((x-0.5)*(x-0.5)+(y-0.5)*(y-0.5))<=0.09)//将满足的豆子计数
{
sum++;
}
}
avge+=(sum/810);
System.out.println(avge/(j+1));//输出到本次撒豆时的平均值
sum=0;
}
// double n=0;
// while(true){
// x=Math.random();
// y=Math.random();
// if(((x-0.5)*(x-0.5)+(y-0.5)*(y-0.5))<=0.09)
// {
// sum++;
// }
// n++;
// System.out.println((sum*100)/(n*9));
// try {
// Thread.sleep(50);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
}
}
实验结果
可以看出当撒豆次数为9000次,每次为9000粒的时候,精确值达到了小数点后3位。
如果有什么不妥的地方,请各位大佬批评指正,谢谢。