蒙特卡罗思维计算圆周率的三种算法
蒙特卡罗思想计算圆周率的三种算法
本篇文章介绍计算圆周率的几种算法,都是应用蒙特卡罗思想:或称计算机随机模拟方法,是一种基于“随机数”的计算方法。
方法一:蒙特卡罗方法,内切圆
1.1思想
有一个以(0,0)为中心的2*2的正方形,及这个正方形的半径为1的内接圆,取这个正方形范围内的一点,则这个点落入内接圆的概率为PI/4。
1.2程序
程序分为两部分:(1)随机生成正方形内的一点(2)计算落入内接圆的概率,从而求得PI。
import java.util.Random; public class MonteCarlo { int m = 0;//落入内接圆的次数 int n = 10000000;//试验进行次数 float x;//点的x坐标值 float y;//点的y坐标值 double result = 0;//结果,即为PI Random r = new Random();//Random对象,用于生成随机数 public static void main(String[] args){ MonteCarlo c = new MonteCarlo(); c.calculatePI(); } public float getNum(){ float tmp = 1-r.nextFloat()*2;//nextFloat生成[0,1]的浮点数 return tmp; } public void calculatePI(){ for(int i = 0; i<n;i++){//进行n次试验 x=getNum(); y=getNum(); float tmp = (float) java.lang.Math.sqrt(x*x+y*y);//开根号 if(tmp<=1) m++;//落入内接圆的次数 } result = (4*(float)m)/n;//PI System.out.println("m: "+m); System.out.println("n: "+n); System.out.println("pi: "+result); } }
方法二:蒲丰投针方法
2.1思想
在平面上画一组间距为d的平行线,将一根长度为l(l<d)的阵任意掷在这个平面上,此阵与平行线中任一条相交的概率是:p = 2l/(PI*d)
2.2程序
程序分为如下几个步骤:(1)随机得到一个点和一个角度(2)计算另一个点位置(都只考虑垂直位置)(3)计算这两个点分别跨越了几条平行线
import java.util.Random; public class PuFeng { int n = 10000000;//试验进行次数 int m = 0;//相交次数 double l = 2;//针的长度 double d = 5;//平行线间距 double pi = 0;//结果 int lNum = 10000;//线的条数 Random r = new Random();//用于生成随机数 public static void main(String[] args){ PuFeng p = new PuFeng(); p.calculatePI(); } public void calculatePI(){ for(int i = 0; i <n;i++){ double point = getPoint(); double angle = getAngle(); double anotherPoint = point+l*java.lang.Math.sin(angle);//得到第二个点垂直位置 int crossNum1 = (int) (point/d);//第一个点前面有几条平行线 int crossNum2 = (int) (anotherPoint/d);//第二个点前面有几条平行线 if((crossNum1-crossNum2)!=0)//若差等于0,则与平行线不相交 m++; } pi= (2*n*l)/(m*d); System.out.println("m: "+m); System.out.println("n: "+n); System.out.println("result: "+pi); } //随机得到平行线范围内的一点 public double getPoint(){ double tmp = r.nextDouble()*lNum*l; return tmp; } //随机得到0~360角度 public double getAngle(){ double tmpAngle = (double) (r.nextDouble()*Math.PI);; return tmpAngle; } }
方法三:互质方法
3.1思想
随机取两个自然数,则这两个数互质的概率为:6/(PI*PI)
3.2程序
该程序分为几个步骤:(1)生成两个自然数(2)判断是否互质(3)计算互质的概率
import java.util.Random; public class PrimeNum { Random r = new Random();//用于生成随机数 int m = 0;//互质的次数 int n = 1000000;//实验次数 float result = 0;//结果,即PI public static void main(String[] args){ PrimeNum p = new PrimeNum(); p.calculatePI(); } public int getNum(){ int tmp = r.nextInt(); while(tmp<1){//r.nextInt()得到了的可能是负数 tmp = r.nextInt(); } return tmp; } public Boolean checkPrime(int a, int b){//判断两个数是否互质 if(a<b){ int tmp = a; a = b; b = tmp; } int c = 0; while((c = a%b)!= 0){ a = b; b = c; } if(b == 1) return true; else return false; } public void calculatePI(){ for(int i = 0; i <n;i++){//进行n次实验 int num1=getNum();//随机获得两个自然数 int num2 = getNum(); if(checkPrime(num1,num2))//判断是否互质 m++;//若互质,则m+1 } result = (float) java.lang.Math.sqrt((6*n)/(float)m); System.out.println("m: "+ m); System.out.println("n: "+ n); System.out.println("result: "+result); } }
- 1楼godfrey902012-12-14 18:25
- 总结的很好!
- Re: shanxing26天前 20:53
- 回复godfrey90n3q,我会继续努力的!