我应该编写一个程序,通过模拟在正方形的内切圆上 throw 飞镖来计算 PI。它将生成 x 和 y 值(坐标点)的随机数,如果 x^2+y^ 小于或等于 1,则飞镖确实击中圆圈,否则没有(错过)。 然后它使用以下公式计算 pi:pi = 4 *(命中/总 throw )。 这有点类似于布冯的针实验。 正如您在下面看到的,我已经编写了代码,但是当我编译它时,pi 的值甚至不接近 3.14 :(
/**
* This program is intended to calculate the value of pi by simulating throwing darts at a dart *board.
*
* @author Nataly Carbonell
* @version 12/13/2014
*/
import java.util.Scanner;
import java.util.Random;
public class Darts
{
public static double[] calcPi(int d, int t)
{
int hit = 0;
int miss = 0;
double [] posX = new double[d];
double [] posY = new double[d];
double[] pi = new double[t];
for(int i = 0; i < t; i++)
{
for(int index = 0; index < d; index++)
{
posX[index] = 2 * Math.random() + - 1;
posY[index] = 2 * Math.random() + - 1;
if((Math.pow(posX[index], 2) + Math.pow(posY[index], 2)) <= 1)
{
hit++;
}
else if ((Math.pow(posX[index], 2) + Math.pow(posY[index], 2))> 1)
{
miss++;
}
}
pi[i] = (4 * (hit / d));
}
return pi;
}
public static double calcPiAverage(double[] p, double t)
{
double average = 0;
double sum = 0;
for(int i = 0; i < t; i++)
{
sum += p[i];
}
average = sum / t;
return average;
}
public static void printOutput(double [] p, double ave, int t)
{
for(int i = 0; i < t; i++)
{
System.out.print("Trial [" + i + "]: pi = ");
System.out.printf("%5.5f%n", p[i]);
}
System.out.printf("Estimate of pi = %5.5f", ave);
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.println("How many darts per trial? ");
int darts = in.nextInt();
System.out.println("How many trials? ");
int trials = in.nextInt();
double [] pi = new double[trials];
pi = calcPi(darts, trials);
double piAverage = calcPiAverage(pi, trials);
printOutput(pi, piAverage, trials);
}
}
最佳答案
主要问题可能是您的整数除法:在此处获取比率之前,将您的 hit
和/或 d
转换为 double
:(4 * (命中/d))
。如果我正确理解您的代码,您可能还想在 index
循环外部但在 i
循环内部重置 hit
。
还有一个想法:这种估计 pi 的蒙特卡罗方法收敛速度极其缓慢,因此您可以采取任何措施来加快速度,都会有所帮助。由于您可以根据 hit
和 d
的值计算 miss
,因此不需要 else if
子句。而且由于您根本不使用 miss
,因此您甚至不需要计算它。 (您还可以通过仅在正 xy 象限中 throw 飞镖来做得更好,但我在下面的代码中没有这样做)。
这是我编辑过的代码:
/**
* This program is intended to calculate the value of pi by simulating throwing darts at a dart *board.
*
* @author Nataly Carbonell
* @version 12/13/2014
*/
import java.util.Scanner;
import java.util.Random;
public class Darts
{
public static double[] calcPi(int d, int t)
{
int hit = 0;
int miss = 0;
double [] posX = new double[d];
double [] posY = new double[d];
double[] pi = new double[t];
for(int i = 0; i < t; i++)
{
hit = 0;
for(int index = 0; index < d; index++)
{
posX[index] = 2 * Math.random() + - 1;
posY[index] = 2 * Math.random() + - 1;
if((Math.pow(posX[index], 2) + Math.pow(posY[index], 2)) <= 1)
{
hit++;
}
}
pi[i] = (4 * ((double)hit / d));
}
return pi;
}
public static double calcPiAverage(double[] p, double t)
{
double average = 0;
double sum = 0;
for(int i = 0; i < t; i++)
{
sum += p[i];
}
average = sum / t;
return average;
}
public static void printOutput(double [] p, double ave, int t)
{
for(int i = 0; i < t; i++)
{
System.out.print("Trial [" + i + "]: pi = ");
System.out.printf("%5.5f%n", p[i]);
}
System.out.printf("Estimate of pi = %5.5f", ave);
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.println("How many darts per trial? ");
int darts = in.nextInt();
System.out.println("How many trials? ");
int trials = in.nextInt();
double [] pi = new double[trials];
pi = calcPi(darts, trials);
double piAverage = calcPiAverage(pi, trials);
printOutput(pi, piAverage, trials);
}
}
关于java - 这个程序有错误吗?模拟投飞镖JAVA计算PI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27465393/