基于Java语言计算PI(π)
划分网格计算π
1.转换扩展法。如果是曲面,而且形状比较规则,可以用转化扩展法。转化扩展法是由节点开始,扩展成线单元,然后扩展成平面的二维单元,然后扩展成三维单元。这样生成的网格质量比较高、速度比较快,不仅可以生成三维网格,也可以生成一维网格和二维网格,还可以进行移动、镜像、拉升、旋转等操作;扫描三维实体的扩展方式、扩展系数和扩展方向,具有灵活、可多方面调整的优势。
2.Delaunay三角形法。如果是由一条封闭曲线围成的连通领域(单连通领域或多连通领域),可以采用Delaunay三角形法。这种方法用等边三角形进行离散,既能照顾到计算对象的细微几何特征,又能照顾到仅需稀疏单元网格之处。Delaunay三角形法适合做局部最优化处理。
3.覆盖法。如果计算对象是完整裁切曲面,且边界为裁剪曲线,可以采用覆盖法。覆盖法主要采用四边形单元进行网格划分。
4.前沿法。前沿法适合划分曲面,四边形单元和三角形单元都可以采用。主要通过把曲面等参变换到二维空间,然后把二维空间映射到三维空间来实现。
该方法类似著名的蒙特卡罗法,不同的是将正方形分成n2个小正方形,统计落在内接圆内的小正方形个数占所有正方形的比例,利用四分之一个圆来研究,看落入其中的小正方形有多少个,并计算概率,再用概率反推π的值,即π=4N/n2 (N表示落入单位圆内小正方形的个数)。
代码部分
package com.zmz.countPI; /** * @ProjectName: PI * @Package: com.zmz.countPI * @ClassName: RandomPI * @Author: 张晟睿 * @Date: 2021/10/20 10:24 * @Version: 1.0 */ public class RandomPI { public static double rand_pi(int n) { int numInCircle = 0; double x, y; double pi; for(int i=0;i < n; i++){ x = Math.random(); y = Math.random(); if(x * x + y * y < 1) numInCircle++; } pi = (4.0 * numInCircle) / n; return pi; } public static void main(String[] args) { System.out.println(rand_pi(10)); //改变参数值 System.out.println(rand_pi(100)); //改变参数值 System.out.println(rand_pi(1000)); //改变参数值 System.out.println(rand_pi(10000)); //改变参数值 System.out.println(rand_pi(100000)); //改变参数值 System.out.println(rand_pi(1000000)); //改变参数值 System.out.println(rand_pi(10000000)); //改变参数值 System.out.println(rand_pi(100000000)); //改变参数值 System.out.println(rand_pi(1000000000)); //改变参数值 } }
测试结果:
次数 | 10 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 |
估计值 | 3.16 | 3.1416000000000004 | 3.141548 | 3.1415905200000003 | 3.1415925455999996 | 3.1415926496239996 | 3.14159265350588 | 3.1415926535868035 | 3.141592654036897 |
可以看出来,该方法投入点的个数越大,越接近真实值。