quinta-feira, 8 de outubro de 2009

Pi revisitado

Já aqui falámos do número Pi, um número irracional que só pode ser calculado por aproximação. Existe um método interessante baseado em ideias probabilísticas. Por essa razão, essas técnicas são conhecidas pelo nome genérico de Método de Monte Carlo. Em que consiste? Suponhamos uma circunferência de raio 1 inscrita num quadrado de lado 2 como mostra a figura.





Sabemos que a área é dada por:


\pi \times R^2


Com o raio R igual a um então a área da circunferência é igual a Pi. Fixemo-nos agora no canto superior direito da figura.





Claramente a área do quarto de círculo é igual à quarta parte de Pi. É aqui que entra o nosso método. Admitamos que a figura acima está afixada numa parede e que nós atiramos dardos em sua direcção. Admitamos também, que todos os dardos acertam na figura e que todos os pontos do quadrado têm a mesma probabilidade de serem atingidos (tecnicamente dizemos que estamos a extrair os pontos de uma distribuição uniforme). Então, ao fim de muitos dardos disparados o número de dardos que caem dentro do quarto de círculo é proporcional à área, ou seja, a Pi/4.

Com base nesta ideia tão simples chegamos ao programa seguinte:




import math
import random

def monte_carlo_pi(num_dardos):
"""
Calcula o valor de pi pelo método de monte Carlo.
"""
# define e inicializa acumulador
conta_dardos_in = 0.0
for i in range(num_dardos):
# gera posição dardo i
x= random.random()
y= random.random()
# calcula distância à origem
d = math.sqrt(x**2 + y**2)
if d <= 1:
conta_dardos_in = conta_dardos_in + 1
res_pi = 4 * (conta_dardos_in/float(num_dardos))
return res_pi




Analisemos o código. Nas linhas 1 e 2 importamos os módulos math e random. O primeiro porque vamos precisar de calcular uma raiz quadrada, o segundo, porque precisamos gerar as coordenadas onde os dardos vão chegar. Em relação ao programa em si saliente-se que temos de resolver duas questões. A primeira, consiste em saber como geramos as coordenadas do dardo; a segunda, liga-se à questão da contagem do número de dardos que caem dentro do círculo. Para a primeira questão, usamos um gerador de números aleatórios que nos fornece números reais no intervalo [0,1] (linhas 12 e 13). Para a segunda questão, basta pensar que, dada a construção (o raio vale 1), todos os pontos a uma distância da origem menor ou igual a 1 caem sobre ou no interior da zona de interesse. A distância (euclidiana) à origem é calculada na linha 15. Na linha 17 contamos os que acertam no quarto de círculo. No final basta multiplicar a percentagem dos que caem dentro por quatro para obter o valor aproximado de Pi (linha 18). Uma nota final para referir que usámos o padrão de programação conhecido por acumulador: neste caso o nome conta_dardos cumpre o papel de contador, com as duas fases de inicialização (linha 9) e actualização (linha 17).

Testemos o programa.


>>> monte_carlo_pi(1000)
3.096
>>> monte_carlo_pi(100000)
3.13612
>>>


Não está mal!

Sem comentários:

Enviar um comentário