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 |
号
另外,如果从0开始,则循环不应达到i<=上限;i<上限