Java 这个程序有错误吗?计算PI模拟飞镖的投掷
我应该写一个程序,通过模拟飞镖在正方形内接圆上的投掷来计算圆周率。它将为x和y值(坐标点)生成随机数,如果x^2+y^小于或等于1,则省道确实击中了圆,否则它不会(未击中)。 然后使用以下公式计算pi:pi=4*(命中/总投掷次数)。 这类似于布冯的针头实验。 正如您在下面看到的,我已经编写了代码,但是当我编译它时,pi的值甚至不接近3.14:(Java 这个程序有错误吗?计算PI模拟飞镖的投掷,java,random,methods,static,Java,Random,Methods,Static,我应该写一个程序,通过模拟飞镖在正方形内接圆上的投掷来计算圆周率。它将为x和y值(坐标点)生成随机数,如果x^2+y^小于或等于1,则省道确实击中了圆,否则它不会(未击中)。 然后使用以下公式计算pi:pi=4*(命中/总投掷次数)。 这类似于布冯的针头实验。 正如您在下面看到的,我已经编写了代码,但是当我编译它时,pi的值甚至不接近3.14:( /** *该程序旨在通过模拟在省道板上投掷省道来计算pi值。 * *@作者Nataly Carbonell *@version 12/13/2014
/**
*该程序旨在通过模拟在省道板上投掷省道来计算pi值。
*
*@作者Nataly Carbonell
*@version 12/13/2014
*/
导入java.util.Scanner;
导入java.util.Random;
公共级飞镖
{
公共静态双[]calcPi(整数d,整数t)
{
int hit=0;
int未命中=0;
double[]posX=新的double[d];
double[]posY=新的double[d];
double[]pi=新的double[t];
for(int i=0;i
主要的问题可能是整数除法:在这里取比率之前,将命中率
和/或d
转换为双精度
:(4*(命中率/d))
。如果我正确理解了您的代码,您可能还希望在索引
循环外,但在I
循环内重置点击
还有一个想法:这种估算pi的蒙特卡罗方法收敛速度非常慢,因此您可以做任何事情来加速它。因为您可以从hit
和d
的值计算miss
,所以您不需要else if
子句。而且因为您根本不使用miss
子句,所以您甚至不需要需要计算。(你也可以通过在正xy象限投掷省道来做得更好,但我在下面的代码中没有这样做)
这是我编辑的您的代码:
/**
* 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);
}
}
/**
*该程序旨在通过模拟在省道板上投掷省道来计算pi值。
*
*@作者Nataly Carbonell
*@version 12/13/2014
*/
导入java.util.Scanner;
导入java.util.Random;
公共级飞镖
{
公共静态双[]calcPi(整数d,整数t)
{
int hit=0;
int未命中=0;
double[]posX=新的double[d];
double[]posY=新的double[d];
double[]pi=新的double[t];
for(int i=0;i if((数学功率(posX[index],2)+数学功率(posY[index],2))如果它没有产生预期的结果,那么是的。听起来你有一个错误。也许你应该试着调试它。我已经试过很多次了。我只是想让其他人检查一下,也许他或她发现了一些我看不到的东西。你得到的pi值到底是什么?因为它要求用户输入,所以它是不同的。但通常是numBER大于5.0,即使值是双精度的,但它们在小数点后永远不会有零。我会尝试这样做:posX[index]=2*Math.random()-1
和posY[index]=2*Math.random()-1
。应该没有理由在那里设置一个+
。好吧,在施法之后,我现在得到小数点后的数字,但是值仍然不接近pi:(在重置了索引外但在I循环内的hit之后,值变短了(小于1),但是仍然不接近pi:(对我来说很有用)(你是否更正了命中计数器的位置?
计数器?--尝试1000000个省道和1次尝试:我得到3.14321(就像我说的,它收敛速度不是很快…)如果我尝试1000000次并且不止一次尝试,我会得到第一次尝试3.14321次,但是其他的尝试都是更大的数字…奇怪。哦,看起来改变命中位置起作用了!^谢谢!我的意思是,是的,每次尝试后命中都必须重置:)谢谢:)
/**
* 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);
}
}