La méthode de Monte Carlo est une méthode de répétition d'essais utilisant des nombres aléatoires. Il est bien connu qu'il existe un moyen de trouver le rapport de circonférence de cette manière, mais ... j'ai soudain pensé. ** Est-ce vraiment plus précis que la méthode simple? ** ... Alors expérimentons réellement.
Imaginez un carré 1 * 1, et mettez un quart de cercle avec un rayon de 1 dedans. Utilisez ** des nombres aléatoires pour obtenir beaucoup ** de points dans ce carré. Soit * N * le nombre de points placés. Si * N * est suffisamment grand, vous pouvez marquer uniformément. Parmi ces points, si les points contenus dans le cercle sont comptés comme * A *, l'aire du carré est 1 et l'aire du quart de cercle est * π / 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; //Nombre d'essais
double x,y;
for (int i = 0; i < n; i++) {
x = r.nextDouble();
y = r.nextDouble();
//Ce point est-il dans le cercle?(La distance entre l'origine et le point est-elle inférieure ou égale à 1?)
if(x * x + y * y <= 1){
cnt++;
}
}
System.out.println((double)cnt / (double)n * 4D);
}
}
Imaginez un carré 1 * 1, et mettez un quart de cercle avec un rayon de 1 dedans. Faites beaucoup de points ** régulièrement espacés ** d'un bout à l'autre de ce carré. Soit * N * le nombre de points placés. Si * N * est suffisamment grand, vous pouvez marquer uniformément. (Autour d'un côté, des points avec seulement la racine carrée de * N * apparaîtront.) Parmi ces points, si les points contenus dans le cercle sont comptés comme * A *, l'aire du carré est 1 et l'aire du quart de cercle est * π / 4 *.
Grid.java
public class Grid {
public static void main(String[] args) {
int cnt = 0;
final int ns = 20000; //Racine carrée du nombre d'essais
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(référence) | |
---|---|---|---|---|---|
Première fois | 3.16 | 3.1396 | 3.139172 | 3.14166432 | 3.14149576 |
Deuxième fois | 3.2 | 3.1472 | 3.1426 | 3.14173924 | 3.1414574 |
troisième fois | 3.08 | 3.1436 | 3.142624 | 3.14167628 | 3.1415464 |
résultat(Médian) | 3.16 | 3.1436 | 3.1426 | 3.14167628 | 3.14149576 |
100(10^2) | 10000(100^2) | 1000000(1000^2) | 100000000(10000^2) | 400000000(référence)(20000^2) | |
---|---|---|---|---|---|
Méthode de Monte Carlo | 3.16 | 3.1436 | 3.1426 | 3.14167628 | 3.14149576 |
Cheval de compétition(la grille) | 2.92 | 3.1156 | 3.139156 | 3.141361 | 3.14147708 |
Valeur idéale | 3.1415926535 | 3.1415926535 | 3.1415926535 | 3.1415926535 | 3.1415926535 |
Taux d'erreur(Monte)[%] | 0.568 | 0.064 | 0.032 | 0.003 | -0.003 |
Taux d'erreur(la grille)[%] | -7.054 | -0.827 | -0.078 | -0.007 | -0.004 |
(Dans mon environnement, l'ordinateur est devenu lourd à partir d'environ 100000000.) Tant que le nombre d'essais est petit, on peut dire que la méthode de Monte Carlo est plus précise. Cependant, l'augmentation de la précision a commencé à diminuer d'environ 100000000, et peut-on dire que c'est la montagne de Seki avec des nombres pseudo-aléatoires?
** Parfois, une attaque aléatoire vaut mieux qu'une attaque totale! ** ** Cela dépend de la précision du nombre pseudo aléatoire utilisé, mais il est également amusant d'utiliser des nombres aléatoires. Cependant, il y a des limites, donc si vous voulez le trouver de manière complètement précise, il existe d'autres méthodes.