Estimando Pi com agulhas e linhas

Há alguns dias, assisti a um vídeo muito legal que mostrava que era possível estimar Pi pelo número de vezes que uma agulha cruzasse linhas verticais num tabuleiro no qual as linhas verticais fossem separadas por uma distância igual ao dobro do tamanho da agulha.

Para testar o que o sujeito fez no vídeo com fósforos, no lugar de agulhas, fiz um programinha em Javascript que deixo abaixo. Como o Javascript não é uma linguagem muito apropriada para isso, não esperem muita precisão nem muita performance. No final do post mostro uma solução mais elegante.

Atenção não coloque mais de 1.000.000 de agulhas ou seu browser pode travar.

Esse método de estimar Pi, é baseado no problema da agulha de Buffon, que foi proposto lá pelo século XVIII, pelo matemático francês Conde de Buffon.

A proposição diz o seguinte: Dada uma agulha com comprimento l e um assoalho com tábuas de largura t, a probabilidade de se jogar uma agulha no chão e ela cair sobre uma junção de tábuas é \frac{2l}{t\pi}.

Se l = \frac{t}{2}, então a probabilidade da agulha cair sobre uma junção é \frac{1}{\pi}

Portanto, se jogarmos N agulhas no chão e o número de agulhas que caírem sobre as junções for h, poderemos aproximar \pi pela fração \frac{N}{h}.

A demonstração dessa probabilidade você encontra aqui. Coloquei o link da Wikipedia em inglês porque essa página na Wikipedia lusófona está muito ruim.

Não satisfeito com a implementação porca que eu fiz em Javascript, o Pedro Paulo resolveu fazer uma muito mais eficiente e elegante em python, que deixo abaixo:

#!/usr/bin/env python
import math, random
 
def generateNeedles (n):
    cross = 0
    for i in xrange(n):
        x = random.random()
        theta = random.random()*(math.pi/2.0)
        if ((x + 0.25*math.cos(theta)) >= 1.0):
            cross += 1
        else:
            if ((x - 0.25*math.cos(theta)) <=0.0):
                cross += 1
    return cross
 
needleCount = 30000000
cross = generateNeedles(needleCount)
print cross,needleCount, needleCount / float(cross)

Ao executar o script acima obtive os seguintes resultados:

30.000 agulhas 3.13217790771
300.000 agulhas 3.14261171985
3.000.000 agulhas 3.14226609757
30.000.000 agulhas 3.1423348868

Esse Conde de Buffon deve ter perdido muita agulha deixando cair entre uma tábua e outra do piso de casa, só pode… 🙂

13 comentários em “Estimando Pi com agulhas e linhas”