The Monte Carlo method is a method of repeating trials using random numbers. It is well known that there is a way to find the pi in this way ... but I suddenly thought. ** Is it really more accurate than the straightforward method? ** ... So let's actually experiment.
Imagine a 1 * 1 square, and put a quarter of a circle with a radius of 1 in it. Use ** random numbers to get a lot of ** points in this square. Let * N * be the number of points placed. If * N * is large enough, you can score evenly. Of these points, if the points contained in the circle are counted as * A *, the area of the square is 1 and the area of the 1/4 circle is * π / 4 *.
Monte.java
import java.util.Random;
public class Monte {
public static void main(String[] args) {
for (int i = 0; i < 3 ; i++) {
monte();
}
}
public static void monte() {
Random r = new Random(System.currentTimeMillis());
int cnt = 0;
final int n = 400000000; //Number of trials
double x,y;
for (int i = 0; i < n; i++) {
x = r.nextDouble();
y = r.nextDouble();
//Is this point in the circle?(Is the distance from the origin to the point 1 or less?)
if(x * x + y * y <= 1){
cnt++;
}
}
System.out.println((double)cnt / (double)n * 4D);
}
}
Imagine a 1 * 1 square, and put a quarter of a circle with a radius of 1 in it. Make a lot of ** evenly spaced ** points from end to end in this square. Let * N * be the number of points placed. If * N * is large enough, you can score evenly. (Around one side, points with only the square root of * N * will appear.) Of these points, if the points contained in the circle are counted as * A *, the area of the square is 1 and the area of the 1/4 circle is * π / 4 *.
Grid.java
public class Grid {
public static void main(String[] args) {
int cnt = 0;
final int ns = 20000; //Square root of number of trials
for (double x = 0; x < ns; x++) {
for (double y = 0; y < ns; y++) {
if(x / (double)(ns - 1) * x / (double)(ns - 1) +
y / (double)(ns - 1) * y / (double)(ns - 1) <= 1D){
cnt++;
}
}
}
System.out.println((double)cnt / ((double)ns * (double)ns) * 4D);
}
}
100 | 10000 | 1000000 | 100000000 | 400000000(reference) | |
---|---|---|---|---|---|
First time | 3.16 | 3.1396 | 3.139172 | 3.14166432 | 3.14149576 |
Second time | 3.2 | 3.1472 | 3.1426 | 3.14173924 | 3.1414574 |
third time | 3.08 | 3.1436 | 3.142624 | 3.14167628 | 3.1415464 |
result(Median) | 3.16 | 3.1436 | 3.1426 | 3.14167628 | 3.14149576 |
100(10^2) | 10000(100^2) | 1000000(1000^2) | 100000000(10000^2) | 400000000(reference)(20000^2) | |
---|---|---|---|---|---|
Monte Carlo method | 3.16 | 3.1436 | 3.1426 | 3.14167628 | 3.14149576 |
Competitive horse(grid) | 2.92 | 3.1156 | 3.139156 | 3.141361 | 3.14147708 |
Ideal value | 3.1415926535 | 3.1415926535 | 3.1415926535 | 3.1415926535 | 3.1415926535 |
Error rate(Monte)[%] | 0.568 | 0.064 | 0.032 | 0.003 | -0.003 |
Error rate(grid)[%] | -7.054 | -0.827 | -0.078 | -0.007 | -0.004 |
(In my environment, the computer became heavy from around 100000000.) As long as the number of trials is small, it can be said that the Monte Carlo method is more accurate. However, the increase in accuracy has begun to decline from around 100000000, and can this be said to be a mountain of seki with pseudo-random numbers?
** Sometimes a random attack is better than a total attack! ** ** It depends on the accuracy of the pseudo-random numbers used, but using random numbers is also fun. However, there are limits, so if you want to find it completely accurately, there are other methods.