domingo, 9 de junio de 2024

Estimar el valor de π (pi) con el Método de Montecarlo en Python 3

Método de Montecarlo

El método de Montecarlo es una técnica computacional basada en la generación de números aleatorios para resolver problemas mediante la simulación de múltiples escenarios posibles. Recibe su nombre por la ciudad de Montecarlo, famosa por su actividad en juegos de azar, donde la aleatoriedad es fundamental.

El método de Montecarlo se basa en el principio de que la aleatoriedad puede ser utilizada para resolver problemas deterministas complejos o calcular valores que pueden ser difíciles o imposibles de obtener utilizando métodos analíticos tradicionales.

La idea fundamental del método de Montecarlo es utilizar la aleatoriedad para muestrear el espacio de entrada de un problema y realizar cálculos estadísticos sobre los resultados obtenidos de estas muestras.

Algunos ejemplos de problemas que se pueden resolver con el método de Montecarlo incluyen:

  1. Estimación de integrales: Utilizando la generación de puntos aleatorios para calcular áreas bajo curvas y, por lo tanto, integrales definidas.
  2. Simulación de sistemas físicos: Modelando el comportamiento de partículas, sistemas térmicos, sistemas cuánticos, etc., mediante la generación de eventos aleatorios que siguen las leyes físicas pertinentes.
  3. Optimización: Explorando el espacio de búsqueda de soluciones mediante la generación de soluciones candidatas de manera aleatoria.
  4. Análisis de riesgos: Evaluando la probabilidad de ocurrencia de eventos inciertos en sistemas complejos.

El método de Montecarlo es muy versátil y se aplica en una amplia gama de disciplinas, incluyendo física, ingeniería, finanzas, biología, entre otras. Su poder radica en su capacidad para proporcionar soluciones aproximadas a problemas complejos mediante la generación de muestras aleatorias y el análisis estadístico de los resultados obtenidos.

Estimar el valor de π (pi)

Un ejemplo sencillo de cómo podrías utilizar el método de Montecarlo para estimar el valor de π (pi), que es la relación entre la circunferencia de un círculo y su diámetro.

El enfoque consiste en generar puntos aleatorios dentro de un cuadrado y contar cuántos de esos puntos están dentro de un círculo inscrito en ese cuadrado. La proporción de puntos dentro del círculo con respecto al total de puntos generados se acerca a la relación entre las áreas del círculo y el cuadrado, que es π/4. Por lo tanto, multiplicando esta proporción por 4, obtenemos una estimación de π.

El código siguiente genera un número especificado de puntos aleatorios dentro del cuadrado unitario (con lados de longitud 1). Luego, verifica si cada punto está dentro del círculo unitario (con radio 1), calculando su distancia al origen (0,0). Después, calcula la proporción de puntos dentro del círculo y utiliza esta proporción para estimar el valor de π, multiplicando por 4. Cuantos más puntos se utilicen en la simulación, más precisa será la estimación.

import random

def estimar_pi(numero_de_puntos):
    puntos_dentro_circulo = 0
    for _ in range(numero_de_puntos):
        x = random.uniform(0, 1)  # Generar coordenadas x e y aleatorias dentro del cuadrado unitario
        y = random.uniform(0, 1)
        distancia_al_centro = x**2 + y**2  # Calcular la distancia al centro del círculo
        if distancia_al_centro <= 1:  # Si la distancia es menor o igual a 1, el punto está dentro del círculo
            puntos_dentro_circulo += 1

    estimacion_pi = 4 * puntos_dentro_circulo / numero_de_puntos
    return estimacion_pi

# Estimar el valor de pi utilizando 10000 puntos
pi_estimado = estimar_pi(10000)
print("Valor estimado de pi:", pi_estimado)

Grafica de estimación de π (pi)

Para graficar el proceso de estimación de π utilizando el método de Montecarlo. En este caso, graficaremos un cuadrado con un círculo inscrito y los puntos aleatorios que se generan para estimar π.

import random
import matplotlib.pyplot as plt

def estimar_pi(numero_de_puntos):
    puntos_dentro_circulo = 0
    puntos_fuera_circulo = 0
    puntos_x_dentro = []
    puntos_y_dentro = []
    puntos_x_fuera = []
    puntos_y_fuera = []
    
    for _ in range(numero_de_puntos):
        x = random.uniform(0, 1)  # Generar coordenadas x e y aleatorias dentro del cuadrado unitario
        y = random.uniform(0, 1)
        distancia_al_centro = x**2 + y**2  # Calcular la distancia al centro del círculo
        
        if distancia_al_centro <= 1:  # Si la distancia es menor o igual a 1, el punto está dentro del círculo
            puntos_dentro_circulo += 1
            puntos_x_dentro.append(x)
            puntos_y_dentro.append(y)
        else:
            puntos_fuera_circulo += 1
            puntos_x_fuera.append(x)
            puntos_y_fuera.append(y)

    estimacion_pi = 4 * puntos_dentro_circulo / numero_de_puntos
    return estimacion_pi, puntos_x_dentro, puntos_y_dentro, puntos_x_fuera, puntos_y_fuera

# Estimar el valor de pi utilizando 10000 puntos
pi_estimado, puntos_x_dentro, puntos_y_dentro, puntos_x_fuera, puntos_y_fuera = estimar_pi(10000)
print("Valor estimado de pi:", pi_estimado)

# Graficar los puntos dentro y fuera del círculo
plt.figure(figsize=(8, 8))
plt.style.use('seaborn')
plt.scatter(puntos_x_fuera, puntos_y_fuera, color='blue', s=5, label='Fuera del círculo')
plt.scatter(puntos_x_dentro, puntos_y_dentro, color='red', s=5, label='Dentro del círculo')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Estimación de pi utilizando el método de Montecarlo')
plt.gca().set_aspect('equal', adjustable='box')
plt.legend()
plt.show()

El gráfico para calcular el valor de π (pi) se muestra a continuación: