随机达特程序

huangapple go评论80阅读模式
英文:

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(&quot;Enter number of tries: &quot;);
        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 &lt; n; i++) {
            if (func &lt;= 1) {
                hit++;
            } else {
                miss++;
            }
        }
        System.out.println(&quot;Probability: &quot; + 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 &lt; n; i++)
          {
        
              if (func &lt;= 1)
                  hit++;
              else
                  miss++;
          }

要么总是增加hit,要么增加miss,因为func的值从不改变。

你想做的是将xyfunc的定义移到循环内部,而不是外部 - 这将使它们每次都不同,正如你打算的那样。

此外,整数除法的结果是一个整数,所以你需要在最后一行将misshit转换为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 &lt; n; i++)
          {
        
              if (func &lt;= 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 doubles 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(&quot;Enter number of tries: &quot;);
        int n = in.nextInt();

        double miss = 0;
        double hit = 0;

        double x = 0, y = 0, func = 0;

        for (int i = 0; i &lt; n; i++)
        {
            x = Math.random() * 2 - 1;
            y = Math.random() * 2 - 1;

            func = x * x + y * y;

            if (func &lt;= 1)
                hit++;
            else
                miss++;
        }

        System.out.println(&quot;Probability: &quot; + ( (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 floatsfor 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.

huangapple
  • 本文由 发表于 2020年7月22日 15:18:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63028854.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定