关于java:当使用伪随机数来估计pi的值时,我得到的值大约为2.44。

When using pseudo random numbers to estimate the value of pi I am getting a value around 2.44. What am I doing wrong?

我正在根据Ernesto Cesaros Therom确定PI的值。我在Java中使用默认的随机方法。我将seed值设置为一个输入,它将确定它将生成多少对随机数。我总是得到2.4494左右的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    import java.util.Random;
import java.util.Scanner;

public class Projectone {
public static int count, sum = 0;
public static int a, b, gd;

public static void main(String[] args) {

    // Enter seed number
    Scanner kb = new Scanner(System.in);
    System.out.print("Enter seed value:");
    int seed = kb.nextInt();
    // Generate pairs of random numbers based on the seed number
    Random rand = new Random();
    for (int i = 0; i <= seed; i++) {
        count++;
        int a = rand.nextInt();
        int b = rand.nextInt();
        // Eliminating all negative numbers
        if (a < 0) {
            a *= -1;
        }
        if (b < 0) {
            b *= -1;
        }
        // Entering random numbers into gcd
        gd = gcd(a, b);
        System.out.println("a =" + a +" b=" + b);
        // breaks loop if gcd is =1 and adds the gcd
        if (gd == 1)
            break;

        for (int j = 0; j <= seed; j++) {
            sum += gd;

        }

    }
    System.out.println("this is the count" + count);
    if (sum == 0) {
        sum = 1;
    }
    System.out.println("The sumation of the gcd's =" + sum);
    //pluging in the values to the ceseros formula
    float pi=(float) Math.sqrt(6.f*count/sum);
    System.out.println("the ans is:"+pi);
}
public static int gcd(int a, int b) {
    while (a != 0 && b != 0) {
        int c = b;
        b = a % b;
        a = c;
    }
    return a + b;
     }
  }

我还想知道如何生成真正的随机数


你应该对定理的状态进行编码,这就是

the probability that two random numbers are coprimes is 6 / pi^2

是0.6079271185。

或另有说明

pi = sqrt(6 / found_probability)

因此

pi = sqrt(6 * tries / found_coprimes)

显然,你需要多次重复这个测试,才能得到圆周率的合理近似值。

现在,在您的代码中:

  • 当你第一次遇到gcd为1(即互质)时,你就停止了迭代。就在那儿,然后比赛就结束了。
  • 然后你开始添加GCD,原因我完全不清楚。得到的GCD值与结果完全无关。

考虑此代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private static int gcd(int a, int b) {
    while (a != 0 && b != 0) {
        int c = b;
        b = a % b;
        a = c;
    }
    return a + b;
}

public static void main(String[] args) {
    Random random = new Random();

    int iv = 1000000;
    int coprime = 0;

    for (int i = 0; i < iv; i++) {
        int int1 = Math.abs(random.nextInt());
        int int2 = Math.abs(random.nextInt());
        if (gcd(int1, int2) == 1) {
            coprime++;
        }
    }
    System.out.println(Math.sqrt(6.0 * iv / coprime));
}

结果是

3.1425778292704583号

关于第二个问题,标准的"随机"数字生成器实际上是伪随机生成器。真正的随机数很难获取,在Java中读取真随机生成


你的数字相对质数的概率是

1
P=number of pairs that are relatively prime/total number of pairs

基于此,您可以重新制定算法:

1
pi=Math.sqrt(6/P)

另外,如果从0开始,则循环不应达到i<=上限;i<上限