用蒙特卡罗方法计算圆周率的近似值,java程序


利用单位圆与边长为1的正方形面积之比来计算

π的近似值具体思想如下:

如图1所示,单位圆的1/4为一个扇形G,它是边长为1


用蒙特卡罗方法计算圆周率的近似值,java程序_第1张图片


的正方形的一部分.考虑扇形面积在正方形面积中所占的比例k,

得出其结果为π/4,然后乘以4就可以得到π的值.这里如何计算比例

k,运用蒙特卡罗方法的随机投点思想.在正方形中随机投入很多点,

使所投点落图1在正方形中每一个位置的机会均等,

然后考察有多少点落在扇形内.其中落在扇形内的点的个数

m与投点总数n之比就是k的近似值.

于是通过java可以完成相应的程序编写.

详细的程序如下.

public class MontePi {

    public static void main(String[] args) {
    
        double x,y=0;
        
        long n=0,i=0;
        for(i=0;i<100000000;i++){
            x= Math.random()*(1-0)+0; //产生0-1的随机数
            y=Math.random();
            if(x*x+y*y<1) n++;
            
        }
        System.out.println(i+":"+n);
        double pi=4*(double)n/(double)i;
        System.out.println(pi);

    }

}

可能的输出结果为:
100000000:78551476
3.14205904

ps:蒙特卡罗分析计算圆周率并不是好方法,显然达不到公元5世纪祖冲之的推算精度。但是在其他领域有独特作用,比如:项目管理里面的风险分析。
蒙特卡罗方法实现了两大优点:
一是简单,省却了繁复的数学推导和演算过程,使得一般人也能够理解和掌握

二是快速。简单和快速,是蒙特卡罗方法在现代项目管理中获得应用的技术基础。


蒙特卡罗分析由于概率计算是相对独立互不影响的,所以很容易发展成大规模并行计算的算法。下面是一个多线程计算圆周率的版本:


import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Random;

public class ThreadMontePi implements Runnable {
    static ArrayList> array1=new ArrayList>() ; //保存结果数据
    private String name;
    private int threadnum;

    public void setName(int threadnum) {
        this.name = threadnum + "";
        this.threadnum = threadnum;
    }

    public void run() {
        long randSeed = System.currentTimeMillis() - threadnum * 10; // 按时间取随机数种子
        //System.out.println(randSeed); //显示随机数种子
        Random rand = new Random(randSeed);
        double x, y = 0;

        long n = 0, i = 0;
        for (i = 0; i < 100000000; i++) {

            x = (double) rand.nextInt(10000000); // 产生0-10000000的随机整数,不包含10000000
            x = x / 10000000d;
            // x= Math.random()*(1-0)+0; //产生0-1的随机数,不包含1
            // y=Math.random();
            y = (double) rand.nextInt(10000000); // 产生0-10000000的随机整数,不包含10000000
            y = y / 10000000d;

            if (x * x + y * y < 1)
                n++;
            // System.out.println(y);
        }
        System.out.println(name + ":" + i + ":" + n);
        Hashtable tabt=new Hashtable();
        tabt.put("i", i);
        tabt.put("n", n);
        array1.set(threadnum, tabt);
        double pi = 4 * (double) n / (double) i;
        System.out.println(name + ":" + pi);

        // System.out.println("hello " + name);
    }

    public static void main(String[] args) {
        //初始化array1
        array1.add(new Hashtable());
        array1.add(new Hashtable());
        array1.add(new Hashtable());
        array1.add(new Hashtable());
        //启动3个线程计算
        ThreadMontePi myThread1 = new ThreadMontePi();
        ThreadMontePi myThread2 = new ThreadMontePi();
        ThreadMontePi myThread3 = new ThreadMontePi();
        myThread1.setName(1);
        Thread thread = new Thread(myThread1);
        thread.start();
        myThread2.setName(2);
        Thread thread2 = new Thread(myThread2);
        thread2.start();
        myThread3.setName(3);
        Thread thread3 = new Thread(myThread3);
        thread3.start();
        
        //判断线程结束,收集计算结果
        boolean flag = true;
        while (flag) {
            Thread.State state = thread.getState();
            Thread.State state2 = thread2.getState();
            Thread.State state3 = thread3.getState();

            if (java.lang.Thread.State.TERMINATED == state
                    && java.lang.Thread.State.TERMINATED == state2
                    && java.lang.Thread.State.TERMINATED == state3)
                break;


        }
        Hashtable tabt=(Hashtable)array1.get(1);
        System.out.println("thread1:"+tabt.get("i")+","+tabt.get("n"));
        Hashtable tabt2=(Hashtable)array1.get(2);
        System.out.println("thread2:"+tabt2.get("i")+","+tabt2.get("n"));
        Hashtable tabt3=(Hashtable)array1.get(3);
        System.out.println("thread3:"+tabt3.get("i")+","+tabt3.get("n"));
        long sumI=tabt.get("i")+tabt2.get("i")+tabt3.get("i");
        long sumN=tabt.get("n")+tabt2.get("n")+tabt3.get("n");
        double pi = 4 * (double) sumN / (double) sumI;
        System.out.println("sumPi:"+pi);    //输出最终计算结果
    }
}


可能的输出结果为:

2:100000000:78545069
2:3.14180276
3:100000000:78536096
3:3.14144384
1:100000000:78540560
1:3.1416224
thread1:100000000,78540560
thread2:100000000,78545069
thread3:100000000,78536096
sumPi:3.141623


你可能感兴趣的:(java,项目管理)