Approximation de π par la méthode de Monte-Carlo en C

CBeginner
Pratiquer maintenant

Introduction

Dans ce laboratoire, nous apprendrons à approximer la valeur de π en utilisant une méthode de Monte Carlo dans le langage C. Nous commencerons par générer des points aléatoires à l'intérieur d'un carré unitaire, puis nous compterons les points qui tombent à l'intérieur d'un quart de cercle pour calculer une approximation de π. Enfin, nous afficherons l'approximation calculée.

Ce laboratoire couvre les étapes clés de la méthode de Monte Carlo pour estimer π, y compris la génération de points aléatoires, le comptage des points à l'intérieur du quart de cercle et l'utilisation du rapport des points à l'intérieur au nombre total de points pour calculer l'approximation. Ce laboratoire fournit une application pratique des concepts de calcul et de géométrie analytique dans le langage C.

Génération de points aléatoires dans un carré unitaire

Dans cette étape, nous allons apprendre à générer des points aléatoires à l'intérieur d'un carré unitaire en utilisant le langage de programmation C, ce qui est essentiel pour la méthode de Monte Carlo visant à approximer π.

Tout d'abord, créons un nouveau fichier C dans le répertoire ~/project pour implémenter la génération de nos points aléatoires :

cd ~/project
nano random_points.c

Maintenant, écrivons le code pour générer les points aléatoires :

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define NUM_POINTS 10000

int main() {
    // Initialiser le générateur de nombres aléatoires
    srand(time(NULL));

    // Générer des points aléatoires dans le carré unitaire
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

        printf("Point %d: (%.4f, %.4f)\n", i + 1, x, y);
    }

    return 0;
}

Décomposons le code :

  • srand(time(NULL)) initialise le générateur de nombres aléatoires avec l'heure actuelle.
  • (double)rand() / RAND_MAX génère un nombre aléatoire entre 0 et 1.
  • Nous générons 10 000 points aléatoires dans le carré unitaire (0,0) à (1,1).

Compilons et exécutons le programme :

gcc random_points.c -o random_points
./random_points

Exemple de sortie :

Point 1: (0.7234, 0.5678)
Point 2: (0.2345, 0.9876)
...
Point 10000: (0.1122, 0.3344)

Compter les points à l'intérieur du quart de cercle et calculer l'approximation de π

Dans cette étape, nous allons modifier notre programme précédent pour compter les points situés à l'intérieur d'un quart de cercle et utiliser ces informations pour approximer la valeur de π.

Mettre à jour le fichier random_points.c :

cd ~/project
nano random_points.c

Remplacer le code précédent par l'implémentation suivante :

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define NUM_POINTS 100000

int main() {
    // Initialiser le générateur de nombres aléatoires
    srand(time(NULL));

    int points_inside_circle = 0;

    // Générer des points aléatoires et compter ceux situés à l'intérieur du quart de cercle
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

        // Vérifier si le point est à l'intérieur du quart de cercle
        if (x*x + y*y <= 1.0) {
            points_inside_circle++;
        }
    }

    // Approximer π
    double pi_approximation = 4.0 * points_inside_circle / NUM_POINTS;

    printf("Points totaux : %d\n", NUM_POINTS);
    printf("Points à l'intérieur du quart de cercle : %d\n", points_inside_circle);
    printf("Approximation de π : %.6f\n", pi_approximation);
    printf("Valeur réelle de π :    %.6f\n", M_PI);
    printf("Différence :        %.6f\n", fabs(pi_approximation - M_PI));

    return 0;
}

Compiler le programme avec la bibliothèque mathématique :

gcc random_points.c -o random_points -lm
./random_points

Exemple de sortie :

Points totaux : 100000
Points à l'intérieur du quart de cercle : 78540
Approximation de π : 3.141600
Valeur réelle de π :    3.141593
Différence :        0.000007

Décomposons les principaux changements :

  • Augmentation du nombre de points pour améliorer la précision.
  • Ajout de la logique pour compter les points à l'intérieur du quart de cercle.
  • Utilisation de la formule : π ≈ 4 * (points à l'intérieur du cercle) / (points totaux).
  • Inclusion de la comparaison avec la valeur réelle de π.

Afficher l'approximation

Dans cette dernière étape, nous allons améliorer notre programme d'approximation de π en créant une fonction pour afficher les résultats et en améliorant la mise en forme de la sortie.

Modifions le fichier random_points.c :

cd ~/project
nano random_points.c

Mettre à jour le code avec une nouvelle fonction d'affichage et une sortie améliorée :

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define NUM_POINTS 1000000

// Fonction pour afficher les résultats de l'approximation de π
void print_pi_approximation(int total_points, int points_inside_circle) {
    double pi_approximation = 4.0 * points_inside_circle / total_points;

    printf("Résultats de l'approximation de π\n");
    printf("=====================\n");
    printf("Points totaux générés :        %d\n", total_points);
    printf("Points à l'intérieur du quart de cercle :  %d\n", points_inside_circle);
    printf("Valeur approximative de π :          %.8f\n", pi_approximation);
    printf("Valeur réelle de π :                %.8f\n", M_PI);
    printf("Différence absolue :           %.8f\n", fabs(pi_approximation - M_PI));
    printf("Précision de l'approximation :        %.4f%%\n",
           (1 - fabs(pi_approximation - M_PI) / M_PI) * 100);
}

int main() {
    // Initialiser le générateur de nombres aléatoires
    srand(time(NULL));

    int points_inside_circle = 0;

    // Générer des points aléatoires et compter ceux situés à l'intérieur du quart de cercle
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

        // Vérifier si le point est à l'intérieur du quart de cercle
        if (x*x + y*y <= 1.0) {
            points_inside_circle++;
        }
    }

    // Afficher les résultats de l'approximation
    print_pi_approximation(NUM_POINTS, points_inside_circle);

    return 0;
}

Compiler et exécuter le programme :

gcc random_points.c -o random_points -lm
./random_points

Exemple de sortie :

Résultats de l'approximation de π
=====================
Points totaux générés :        1000000
Points à l'intérieur du quart de cercle :  785398
Valeur approximative de π :          3.14159200
Valeur réelle de π :                3.14159265
Différence absolue :           0.00000065
Précision de l'approximation :        99.9998%

Améliorations clés :

  • Création d'une fonction dédiée print_pi_approximation().
  • Augmentation du nombre de points à 1 000 000 pour une meilleure précision.
  • Ajout d'une mise en forme de sortie plus détaillée.
  • Inclusion du pourcentage de précision de l'approximation.

Résumé

Dans ce laboratoire, nous avons d'abord appris à générer des points aléatoires à l'intérieur d'un carré unité en utilisant le langage C, ce qui est essentiel pour la méthode de Monte Carlo permettant d'approximer π. Nous avons initialisé le générateur de nombres aléatoires avec l'heure actuelle, puis généré 10 000 points aléatoires dans le carré unité (0,0) à (1,1) en utilisant la fonction rand().

Ensuite, nous avons modifié le programme pour compter les points à l'intérieur d'un quart de cercle et utilisé ces informations pour approximer la valeur de π. Nous avons généré 100 000 points aléatoires et vérifié lesquels tombaient à l'intérieur du quart de cercle. En calculant le rapport entre le nombre de points à l'intérieur du cercle et le nombre total de points, nous avons pu estimer la valeur de π.