Näherungsweise Berechnung von π mit der Monte-Carlo-Methode in C

CCBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Labor lernen wir, wie man den Wert von π mithilfe der Monte-Carlo-Methode in der Programmiersprache C approximiert. Wir beginnen mit der Erzeugung zufälliger Punkte innerhalb eines Einheitsquadrats und zählen anschließend die Punkte, die innerhalb eines Viertelkreises liegen, um eine Näherung von π zu berechnen. Schließlich geben wir die berechnete Näherung aus.

Das Labor deckt die wichtigsten Schritte der Monte-Carlo-Methode zur Schätzung von π ab, einschließlich der Erzeugung zufälliger Punkte, der Zählung der Punkte innerhalb des Viertelkreises und der Verwendung des Verhältnisses von Punkten innerhalb des Viertelkreises zu den Gesamtpunkten zur Berechnung der Näherung. Dieses Labor bietet eine praktische Anwendung von Kalkül- und analytisch-geometrischen Konzepten in der Programmiersprache C.

Zufällige Punkte in einem Einheitsquadrat generieren

In diesem Schritt lernen wir, wie man zufällige Punkte innerhalb eines Einheitsquadrats mit der Programmiersprache C generiert, ein entscheidender Bestandteil der Monte-Carlo-Methode zur Approximation von π.

Erstellen wir zunächst eine neue C-Datei im Verzeichnis ~/project zur Implementierung der Zufallszahlengenerierung:

cd ~/project
nano random_points.c

Schreiben wir nun den Code zur Generierung der Zufallszahlen:

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

#define NUM_POINTS 10000

int main() {
    // Den Zufallszahlengenerator mit der aktuellen Zeit initialisieren
    srand(time(NULL));

    // Zufällige Punkte im Einheitsquadrat generieren
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

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

    return 0;
}

Zerlegung des Codes:

  • srand(time(NULL)) initialisiert den Zufallszahlengenerator mit der aktuellen Zeit.
  • (double)rand() / RAND_MAX generiert eine Zufallszahl zwischen 0 und 1.
  • Wir generieren 10.000 zufällige Punkte im Einheitsquadrat (0,0) bis (1,1).

Kompilieren und ausführen des Programms:

gcc random_points.c -o random_points
./random_points

Beispielausgabe:

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

Punkte im Viertelkreis zählen und π approximieren

In diesem Schritt modifizieren wir unser vorheriges Programm, um die Punkte innerhalb eines Viertelkreises zu zählen und diese Informationen zur Approximation des Wertes von π zu verwenden.

Aktualisieren wir die Datei random_points.c:

cd ~/project
nano random_points.c

Ersetzen Sie den vorherigen Code durch die folgende Implementierung:

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

#define NUM_POINTS 100000

int main() {
    // Den Zufallszahlengenerator initialisieren
    srand(time(NULL));

    int points_inside_circle = 0;

    // Zufällige Punkte generieren und diejenigen zählen, die innerhalb des Viertelkreises liegen
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

        // Überprüfen, ob der Punkt innerhalb des Viertelkreises liegt
        if (x*x + y*y <= 1.0) {
            points_inside_circle++;
        }
    }

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

    printf("Gesamtzahl der Punkte: %d\n", NUM_POINTS);
    printf("Punkte innerhalb des Viertelkreises: %d\n", points_inside_circle);
    printf("Approximation von π: %.6f\n", pi_approximation);
    printf("Exakter Wert von π:    %.6f\n", M_PI);
    printf("Differenz:        %.6f\n", fabs(pi_approximation - M_PI));

    return 0;
}

Kompilieren Sie das Programm mit der Mathematikbibliothek:

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

Beispielausgabe:

Gesamtzahl der Punkte: 100000
Punkte innerhalb des Viertelkreises: 78540
Approximation von π: 3.141600
Exakter Wert von π:    3.141593
Differenz:        0.000007

Zusammenfassend:

  • Die Anzahl der Punkte wurde erhöht, um die Genauigkeit zu verbessern.
  • Es wurde Logik hinzugefügt, um Punkte innerhalb des Viertelkreises zu zählen.
  • Die Formel π ≈ 4 * (Punkte im Kreis) / (Gesamtzahl der Punkte) wurde verwendet.
  • Der Vergleich mit dem tatsächlichen Wert von π wurde eingefügt.

Die Approximation ausgeben

In diesem letzten Schritt verbessern wir unser π-Approximationsprogramm, indem wir eine Funktion zum Ausgeben der Ergebnisse erstellen und die Ausgabeformatierung optimieren.

Ändern wir die Datei random_points.c:

cd ~/project
nano random_points.c

Aktualisieren Sie den Code mit einer neuen Ausgabefunktion und einer verbesserten Ausgabe:

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

#define NUM_POINTS 1000000

// Funktion zum Ausgeben der Approximationsergebnisse
void print_pi_approximation(int total_points, int points_inside_circle) {
    double pi_approximation = 4.0 * points_inside_circle / total_points;

    printf("π Approximationsergebnisse\n");
    printf("=====================\n");
    printf("Generierte Gesamtzahl der Punkte:        %d\n", total_points);
    printf("Punkte im Viertelkreis:  %d\n", points_inside_circle);
    printf("Approximierter π-Wert:          %.8f\n", pi_approximation);
    printf("Exakter π-Wert:                %.8f\n", M_PI);
    printf("Absoluter Unterschied:           %.8f\n", fabs(pi_approximation - M_PI));
    printf("Genauigkeit der Approximation:        %.4f%%\n",
           (1 - fabs(pi_approximation - M_PI) / M_PI) * 100);
}

int main() {
    // Den Zufallszahlengenerator initialisieren
    srand(time(NULL));

    int points_inside_circle = 0;

    // Zufällige Punkte generieren und diejenigen zählen, die innerhalb des Viertelkreises liegen
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

        // Überprüfen, ob der Punkt innerhalb des Viertelkreises liegt
        if (x*x + y*y <= 1.0) {
            points_inside_circle++;
        }
    }

    // Ausgabe der Approximationsergebnisse
    print_pi_approximation(NUM_POINTS, points_inside_circle);

    return 0;
}

Kompilieren und ausführen des Programms:

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

Beispielausgabe:

π Approximationsergebnisse
=====================
Generierte Gesamtzahl der Punkte:        1000000
Punkte im Viertelkreis:  785398
Approximierter π-Wert:          3.14159200
Exakter π-Wert:                3.14159265
Absoluter Unterschied:           0.00000065
Genauigkeit der Approximation:        99.9998%

Wichtige Verbesserungen:

  • Erstellung einer dedizierten Funktion print_pi_approximation().
  • Erhöhung der Punktanzahl auf 1.000.000 für höhere Genauigkeit.
  • Detailliertere Ausgabeformatierung.
  • Einschließlich der Genauigkeit der Approximation in Prozent.

Zusammenfassung

In diesem Labor haben wir zunächst gelernt, wie man mit der Programmiersprache C zufällige Punkte innerhalb eines Einheitsquadrats generiert, ein entscheidender Schritt der Monte-Carlo-Methode zur Approximation von π. Wir haben den Zufallszahlengenerator mit der aktuellen Zeit initialisiert und anschließend 10.000 zufällige Punkte im Einheitsquadrat (0,0) bis (1,1) mithilfe der Funktion rand() generiert.

Als Nächstes haben wir das Programm modifiziert, um die Punkte innerhalb eines Viertelkreises zu zählen und diese Informationen zur Approximation von π zu verwenden. Wir haben 100.000 zufällige Punkte generiert und geprüft, welche innerhalb des Viertelkreises lagen. Durch die Berechnung des Verhältnisses der Punkte innerhalb des Kreises zur Gesamtzahl der Punkte konnten wir den Wert von π schätzen.