英文:
Random Dart Program
问题
我遇到了这个问题,它出现在Cay Horstmann的书中:
编写以下模拟程序:将飞镖随机投向具有角点(1,1)和(-1,-1)的正方形。如果飞镖落在单位圆内(即,以中心(0,0)和半径1的圆),则算命中。否则算失误。运行这个模拟并使用它来确定π的近似值。如果您能解释为什么这比Buffon针程序更好地估计π,将获得额外的学分。
我理解为什么这种方法估计π比Buffon针程序更好,所以这部分不需要翻译。但是我似乎在我的代码中遇到了问题。
以下是我的当前代码:
import java.util.Scanner;
public class Dart {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter number of tries: ");
int n = in.nextInt();
int miss = 0;
int hit = 0;
double x = Math.random() * 2 - 1;
double y = Math.random() * 2 - 1;
double func = x * x + y * y;
for (int i = 0; i < n; i++) {
if (func <= 1) {
hit++;
} else {
miss++;
}
}
System.out.println("Probability: " + hit / (hit + miss) * 4);
}
}
当我输入任何数字时,概率输出总是为1,但我认为如果代码正确的话,它应该打印π,因为它是:(半径为1的圆的面积)除以(边长为2的正方形)乘以4。
我希望您能解释为什么我的代码有问题。
英文:
I came across this question in the Cay Horstmann book:
Program the following simulation: Darts are thrown at random points onto the
square with corners (1,1) and (−1,−1). If the dart lands inside the unit circle (that is,
the circle with center (0,0) and radius 1), it is a hit. Otherwise it is a miss. Run this
simulation and use it to determine an approximate value for π. Extra credit if you
explain why this is a better method for estimating π than the Buffon needle
program.
I do get why this is a better method for estimating π than the Buffon needle
program, so that is fine. But I seem to have problems with my code.
Here is my current code:
import java.util.Scanner;
public class Dart {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter number of tries: ");
int n = in.nextInt();
int miss = 0;
int hit = 0;
double x = Math.random() * 2 - 1;
double y = Math.random() * 2 - 1;
double func = x * x + y * y;
for (int i = 0; i < n; i++) {
if (func <= 1) {
hit++;
} else {
miss++;
}
}
System.out.println("Probability: " + hit / (hit + miss) * 4);
}
}
When I enter any numbers, the Probability output always comes out as 1, but I think if the code is right it prints π because its: (the area of a circle with radius 1) over (a square with length 2) times 4.
I would appreciate an explanation why my code is wrong.
答案1
得分: 1
当你赋值给一个变量时,该变量不会每次被请求时重新计算 - 它只会被赋值一次,直到被重新赋值之前,它的值始终保持不变。所以这个:
double x = Math.random() * 2 - 1;
double y = Math.random() * 2 - 1;
double func = x * x + y * y;
会将x和y设置为-1到1之间的随机数,并将func设置为x * x + y * y
...然后它们会保持不变,直到程序结束,因为你从未重新赋值它们。
所以这个:
for (int i = 0; i < n; i++)
{
if (func <= 1)
hit++;
else
miss++;
}
要么总是增加hit
,要么增加miss
,因为func
的值从不改变。
你想做的是将x
、y
和func
的定义移到循环内部,而不是外部 - 这将使它们每次都不同,正如你打算的那样。
此外,整数除法的结果是一个整数,所以你需要在最后一行将miss
和hit
转换为double
。
英文:
When you assign a variable, that variable isn't recalculated every time it's asked for--it's assigned once, and until it's reassigned, it'll always be the same value. So this:
double x = Math.random() * 2 - 1;
double y = Math.random() * 2 - 1;
double func = x * x + y * y;
will set x and y to a random number between -1 and 1, and func to x * x + y * y
... and then they'll stay that way, until the program ends, because you never reassign them.
So this:
for (int i = 0; i < n; i++)
{
if (func <= 1)
hit++;
else
miss++;
}
will either always increment hit
or increment miss
, because func
's value never changes.
What you want to do is move the definitions of x
, y
and func
to inside the for loop, rather than outside--this will make them different every time, as you intended.
Also, integer division results in an integer, so you're going to need to convert miss
and hit
into double
s in the last line.
答案2
得分: 0
尝试以下代码:
import java.util.Scanner;
public class Dart
{
public static void main(String[]args)
{
Scanner in = new Scanner(System.in);
System.out.println("输入尝试次数:");
int n = in.nextInt();
double miss = 0;
double hit = 0;
double x = 0, y = 0, func = 0;
for (int i = 0; i < n; i++)
{
x = Math.random() * 2 - 1;
y = Math.random() * 2 - 1;
func = x * x + y * y;
if (func <= 1)
hit++;
else
miss++;
}
System.out.println("概率: " + ((double) hit / (hit + miss) * 4));
}
}
你犯了两个错误,第一个是需要在循环内生成随机的x和y值,以便重新生成值,第二个是你需要使用`doubles`或`floats`来表示hit和miss,或者更好的方式(感谢@FedericoklezCullocafor的建议),你可以在`print`内将它们转换为doubles,因为如果你在`print`中使用`int`,将进行整数除法,总是返回0。
英文:
Try out the following
import java.util.Scanner;
public class Dart
{
public static void main(String[]args)
{
Scanner in = new Scanner(System.in);
System.out.println("Enter number of tries: ");
int n = in.nextInt();
double miss = 0;
double hit = 0;
double x = 0, y = 0, func = 0;
for (int i = 0; i < n; i++)
{
x = Math.random() * 2 - 1;
y = Math.random() * 2 - 1;
func = x * x + y * y;
if (func <= 1)
hit++;
else
miss++;
}
System.out.println("Probability: " + ( (double) hit / (hit + miss) * 4 ));
}
}
You made 2 mistakes first one you need to generate the random x and y within the loop so the values get regenerated and secondly you need to use doubles
or floats
for hit and miss or the better way ( thanks to @FedericoklezCullocafor ) you could cast them to doubles within the print
because if you would use int
down in the print
you would make an integer division which returns always 0.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论