1
votes

L'estimation de pi avec une méthode de Monte Carlo donne une valeur plus grande que prévu

J'essaie d'estimer pi en divisant les aires d'un carré et de son cercle intégré, mais j'obtiens ~ 3,66.

Est-ce que quelqu'un voit ce que je fais mal?

inCount=0
outCount=0
it=1000000
L=100
for i in range(it):
    xran=rnd.random()*L
    yran=rnd.random()*L
    xc=abs(0.5*L-xran)
    yc=abs(0.5*L-yran)
    r=np.sqrt((xc**2)+(yc**2))
    if r<0.5*L:
        inCount=inCount+1
    if r>0.5*L:
        outCount=outCount+1
    if r==0.5*L:
        inCount=inCount+1
        outCount=outCount+1
pigen=inCount/outCount
print('pi generated: '+np.str(pigen))


3 commentaires

Pouvez-vous ajouter vos importations au code?


Cela peut ne pas fonctionner, mais essayez plutôt math.sqrt ()


Pourquoi L = 100 ? Vous ne pouvez pas le faire avec L = 1 ?


4 Réponses :


7
votes

Vous avez

inCount=0
outCount=0
it=1000000
L=100
for i in range(it):
    xran=rnd.random()*L
    yran=rnd.random()*L
    xc=abs(0.5*L-xran)
    yc=abs(0.5*L-yran)
    r=np.sqrt((xc**2)+(yc**2))
    if r<0.5*L:
        inCount=inCount+1
    elif r>0.5*L:
        outCount=outCount+1
    else:
        inCount=inCount+1
        outCount=outCount+1
pigen=pigen=4*inCount/(inCount+outCount)
print('pi generated: '+np.str(pigen))

qui donne la proportion de coups à l'intérieur et à l'extérieur du rayon.

Notez que pi / (4-pi) = 3.659792 ... qui est ce que votre code estime actuellement.

Vous avez besoin de

if r<0.5*L:
    inCount=inCount+1
elif r>0.5*L:
    outCount=outCount+1
else:
    inCount=inCount+1
    outCount=outCount+1

qui vous donnera quatre fois la proportion de hits à l'intérieur par rapport au total, c'est-à-dire pi .


Notez également que votre code est actuellement

if r<0.5*L:
    inCount=inCount+1
if r>0.5*L:
    outCount=outCount+1
if r==0.5*L:
    inCount=inCount+1
    outCount=outCount+1

qui peut être simplifié avec elif / else . Puisque r ne peut pas être à la fois supérieur et inférieur à L , le deuxième if peut devenir un elif . De même, si r n'est ni inférieur ni supérieur à L , alors il doit être égal, donc le troisième if code > peut simplement devenir un else .

pigen=4*inCount/(inCount+outCount)

Cela évitera des comparaisons inutiles de r et L code> dans votre code.


Votre code final serait alors

pigen=inCount/outCount


3 commentaires

C'était presque vrai! J'avais aussi oublié d'ajouter un 4.


Voulez-vous dire 4 * cela?


Ah, oui - dans ma hâte, j'ai oublié cela.



1
votes
pigen=inCount/(outCount+inCount)*4

0 commentaires

0
votes

Wai Ha Lee avait presque raison! J'avais aussi oublié d'ajouter un 4.

Si quelqu'un veut savoir comment ça se passe, c'est comme ça (et oui, L peut être ce que tu veux):

import numpy as np
import random as rnd
inCount=0
outCount=0
it=1000000
L=100
for i in range(it):
    xran=rnd.random()*L
    yran=rnd.random()*L
    xc=abs(0.5*L-xran)
    yc=abs(0.5*L-yran)
    r=np.sqrt((xc**2)+(yc**2))
    if r<0.5*L:
        inCount=inCount+1
    if r>0.5*L:
        outCount=outCount+1
    if r==0.5*L:
        inCount=inCount+1
        outCount=outCount+1
pigen=4*inCount/(inCount+outCount)
print('pi generat: '+np.str(pigen))

p>


0 commentaires

0
votes

inCount indique le nombre de points dans un cercle de rayon r = L / 2 et outCount indique le nombre de points dans un carré contenant exactement ce cercle, mais pas dans le cercle lui-même.

inCount est proportionnel à pi * r ** 2 et outCount est proportionnel à L ** 2 - pi * r ** 2 = (4 - pi) * r ** 2 . Lorsque vous prenez le ratio, vous obtenez pi / (4 - pi) = 3,66 .

Comme l'a souligné Wai Ha Lee, vous devez calculer 4 * inCount / (inCount + outCount) = pi .


0 commentaires