Pergunta

Estou fazendo um experimento de Monte Carlo para calcular uma aproximação da PI. De SICP:

O método de Monte Carlo é composto por escolher experimentos amostra ao acaso a partir de um grande conjunto e tomada de seguida deduções sobre a base da probabilidades estimada a partir de tabular os resultados daqueles experimentos. Por exemplo, nós podemos aproximar usando o fato de que 6 / pi ^ 2 é a probabilidade de que dois inteiros escolhidos aleatoriamente não terá Factores em comum; isto é, que a sua maior divisor comum será 1. Para obter a aproximação, nós realizar um grande número de experiências. Em cada experimento que escolher dois inteiros aleatoriamente e realizar um teste para ver se o GCD é 1. A fração de vezes que o teste é passado dá -nos a nossa estimativa de 6 / pi ^ 2 e, a partir isso obtemos a nossa aproximação pi.

Mas quando eu executar o meu programa que eu obter valores como 3,9 ...

Aqui está o meu programa:

(define (calculate-pi trials)
  (define (this-time-have-common-factors?)
    (define (get-rand)
      (+ (random 9999999999999999999999999999999) 1))
    (= (gcd (get-rand) (get-rand)) 1))
  (define (execute-experiment n-times acc)
    (if (> n-times 0)
        (if (this-time-have-common-factors?)
            (execute-experiment (- n-times 1) acc)
            (execute-experiment (- n-times 1) (+ acc 1)))
        acc))
  (define n-success (execute-experiment trials 0))
  (define prob (/ n-success trials))
  (sqrt (/ 6 prob)))

Meu intérprete é MIT / GNU 7.7.90

Obrigado por qualquer ajuda.

Foi útil?

Solução

Bem, para responder sua pergunta diretamente, você tem as para trás se-afirmação; deve ser desta forma.

    (if (this-time-have-common-factors?)
        (execute-experiment (- n-times 1) (+ acc 1)
        (execute-experiment (- n-times 1) acc))

Então, você está calculando 1-6 / p 2 no limite como o # de ensaios se aproxima do infinito. Este rendimento de "pi" = sqrt (6 / (1-6 / p 2 )) = sqrt (6p 2 / (p 2 - 6)) = 3,911).


Vamos dar um passo para trás aqui, embora, e olhar para o que o método de Monte Carlo faz por nós com esse cálculo (dica: esperar a convergência muito lenta Quantas vezes você está executando-o.?) ...

Cada ensaio quer nos dá 0 ou 1, com uma probabilidade de p = 6 / p 2 . Este é um exemplo de uma Bernoulli processo, que tem, para o número de um de m em um certo número de ensaios n , um binomial distribuição .

Considere ? = m / n, a fracção de vezes que passam o teste comuns-divisores. Isto tem um valor médio de p e uma variância de p (1-p) / n, ou Desv s ? = sqrt (p (1-p) / n). Para n = 10000, você deve esperar um dev std de 0,00488. 95% do tempo você será dentro de 2 devs std da média, e 5% do tempo você vai estar fora 2 devs std, ou entre 0,5982 e 0,6177. Assim, uma estimativa de p a partir deste método, dado n = 10000, irá estar compreendida entre 3,117 e 3,167 a 95% do tempo e fora desta gama de 5% do tempo.

Se você quiser aumentar o número de ensaios por 100, que reduz dev std por um fator de 10 e a estimativa de p se estreitou entre 3,1391 e 3,1441 com 95% de confiança.

métodos de Monte Carlo são agradáveis ??para uma estimativa aproximada mas eles precisam de lotes e lotes de ensaios para uma resposta precisa, e, geralmente, chegar a um ponto de retornos decrescentes.

Não que esta é uma maneira infrutífera de pi aproximada, basta estar ciente do problema.

Outras dicas

eu encontrar o meu erro. Obrigado a todos. Eu estava incrementando os casos de sucesso no lugar errado.

O código corrigido é:

(define (calculate-pi trials)
  (define (this-time-have-common-factors?)
    (define (get-rand)
      (+ (random 9999999) 1))
    (= (gcd (get-rand) (get-rand)) 1))
  (define (execute-experiment n-times acc)
    (if (> n-times 0)
        (if (this-time-have-common-factors?)
            (execute-experiment (- n-times 1) (+ acc 1))
            (execute-experiment (- n-times 1) acc))
        acc))
  (define n-success (execute-experiment trials 0))
  (define prob (/ n-success trials))
  (sqrt (/ 6 prob)))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top