Aproximar π Usando o Método de Monte Carlo em C

CBeginner
Pratique Agora

Introdução

Neste laboratório, aprenderemos a aproximar o valor de π usando um método de Monte Carlo na linguagem de programação C. Começaremos gerando pontos aleatórios dentro de um quadrado unitário, em seguida, contaremos os pontos que caem dentro de um quarto de círculo para calcular uma aproximação de π. Finalmente, imprimiremos a aproximação calculada.

O laboratório cobre os passos-chave do método de Monte Carlo para estimar π, incluindo a geração de pontos aleatórios, a contagem de pontos dentro do quarto de círculo e o uso da razão entre os pontos dentro e o total de pontos para calcular a aproximação. Este laboratório fornece uma aplicação prática dos conceitos de cálculo e geometria analítica na linguagem de programação C.

Gerar Pontos Aleatórios em um Quadrado Unitário

Neste passo, aprenderemos a gerar pontos aleatórios dentro de um quadrado unitário usando a linguagem de programação C, parte crucial do método de Monte Carlo para aproximar π.

Primeiro, crie um novo arquivo C no diretório ~/project para implementar a geração de pontos aleatórios:

cd ~/project
nano random_points.c

Agora, vamos escrever o código para gerar os pontos:

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

#define NUM_POINTS 10000

int main() {
    // Inicializa o gerador de números aleatórios
    srand(time(NULL));

    // Gera pontos aleatórios no quadrado unitário
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

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

    return 0;
}

Vamos analisar o código:

  • srand(time(NULL)) inicializa o gerador de números aleatórios com a hora atual.
  • (double)rand() / RAND_MAX gera um número aleatório entre 0 e 1.
  • Geramos 10.000 pontos aleatórios no quadrado unitário (0,0) a (1,1).

Compile e execute o programa:

gcc random_points.c -o random_points
./random_points

Exemplo de saída:

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

Contar Pontos Dentro do Quarto de Círculo e Calcular a Aproximação de π

Neste passo, modificaremos o nosso programa anterior para contar os pontos dentro de um quarto de círculo e usar esta informação para aproximar o valor de π.

Atualizemos o arquivo random_points.c:

cd ~/project
nano random_points.c

Substitua o código anterior pela seguinte implementação:

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

#define NUM_POINTS 100000

int main() {
    // Inicializa o gerador de números aleatórios
    srand(time(NULL));

    int pontos_dentro_circulo = 0;

    // Gera pontos aleatórios e conta aqueles dentro do quarto de círculo
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

        // Verifica se o ponto está dentro do quarto de círculo
        if (x*x + y*y <= 1.0) {
            pontos_dentro_circulo++;
        }
    }

    // Aproxima π
    double aproximacao_pi = 4.0 * pontos_dentro_circulo / NUM_POINTS;

    printf("Pontos totais: %d\n", NUM_POINTS);
    printf("Pontos dentro do quarto de círculo: %d\n", pontos_dentro_circulo);
    printf("Aproximação de π: %.6f\n", aproximacao_pi);
    printf("Valor real de π:    %.6f\n", M_PI);
    printf("Diferença:        %.6f\n", fabs(aproximacao_pi - M_PI));

    return 0;
}

Compile o programa com a biblioteca matemática:

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

Exemplo de saída:

Pontos totais: 100000
Pontos dentro do quarto de círculo: 78540
Aproximação de π: 3.141600
Valor real de π:    3.141593
Diferença:        0.000007

Vamos analisar as principais mudanças:

  • Aumentou o número de pontos para melhorar a precisão.
  • Adicionou lógica para contar pontos dentro do quarto de círculo.
  • Usou a fórmula: π ≈ 4 * (pontos dentro do círculo) / (pontos totais).
  • Incluiu a comparação com o valor real de π.

Imprimir a Aproximação

Neste passo final, melhoraremos o nosso programa de aproximação de π criando uma função para imprimir os resultados e melhorar a formatação da saída.

Modifiquemos o arquivo random_points.c:

cd ~/project
nano random_points.c

Atualize o código com uma nova função de impressão e saída aprimorada:

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

#define NUM_POINTS 1000000

// Função para imprimir os resultados da aproximação
void print_pi_approximation(int total_points, int pontos_dentro_circulo) {
    double aproximacao_pi = 4.0 * pontos_dentro_circulo / total_points;

    printf("Resultados da Aproximação de π\n");
    printf("==============================\n");
    printf("Pontos Totais Gerados:        %d\n", total_points);
    printf("Pontos Dentro do Quarto de Círculo:  %d\n", pontos_dentro_circulo);
    printf("Valor Aproximado de π:          %.8f\n", aproximacao_pi);
    printf("Valor Real de π:                %.8f\n", M_PI);
    printf("Diferença Absoluta:           %.8f\n", fabs(aproximacao_pi - M_PI));
    printf("Precisão da Aproximação:        %.4f%%\n",
           (1 - fabs(aproximacao_pi - M_PI) / M_PI) * 100);
}

int main() {
    // Inicializa o gerador de números aleatórios
    srand(time(NULL));

    int pontos_dentro_circulo = 0;

    // Gera pontos aleatórios e conta aqueles dentro do quarto de círculo
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

        // Verifica se o ponto está dentro do quarto de círculo
        if (x*x + y*y <= 1.0) {
            pontos_dentro_circulo++;
        }
    }

    // Imprime os resultados da aproximação
    print_pi_approximation(NUM_POINTS, pontos_dentro_circulo);

    return 0;
}

Compile e execute o programa:

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

Exemplo de saída:

Resultados da Aproximação de π
==============================
Pontos Totais Gerados:        1000000
Pontos Dentro do Quarto de Círculo:  785398
Valor Aproximado de π:          3.14159200
Valor Real de π:                3.14159265
Diferença Absoluta:           0.00000065
Precisão da Aproximação:        99.9998%

Melhorias chave:

  • Criou uma função dedicada print_pi_approximation().
  • Aumentou os pontos para 1.000.000 para melhor precisão.
  • Adicionou formatação de saída mais detalhada.
  • Incluiu a porcentagem de precisão da aproximação.

Resumo

Neste laboratório, aprendemos inicialmente a gerar pontos aleatórios dentro de um quadrado unitário usando a linguagem C, um passo crucial no método de Monte Carlo para aproximar o valor de π. Inicialmente, a semente do gerador de números aleatórios foi definida com a hora atual e, em seguida, 10.000 pontos aleatórios foram gerados no quadrado unitário (0,0) a (1,1) utilizando a função rand().

Em seguida, modificamos o programa para contar os pontos dentro de um quarto de círculo e utilizamos essa informação para aproximar o valor de π. Geramos 100.000 pontos aleatórios e verificamos quais deles caíram dentro do quarto de círculo. Calculando a razão entre os pontos dentro do círculo e o número total de pontos, conseguimos estimar o valor de π.