2013-09-10 4 views
0

Я пытаюсь определить количество мраморов, попадающих в данный круг (радиус 1), учитывая, что они имеют случайные координаты x и y.Схема Монте-Карло-выборка

Моя общая цель - найти приблизительное значение для pi, используя взятие monte carlo путем умножения на 4 (количество мраморов в круге)/(общее количество мрамора).

Я предназначил для своей функции подсчет количества шариков внутри круга, но у меня возникают проблемы с тем, почему это не работает. Любая помощь по выполнению функции здесь будет оценена по достоинству.

Прошу прокомментировать, если мой запрос выше для получения помощи неясен.

(define(monte-carlo-sampling n) 
(let ((x (- (* 2 (random)) 1)) 
     (y (- (* 2 (random)) 1))) 
(cond((= 0 n) 
    * 4 (/ monte-carlo-sampling(+ n 1) n) 
    ((> 1 n) 
    (cond((< 1 (sqrt(+ (square x) (square y))) (+ 1 (monte-carlo-sampling(- n 1))))) 
     ((> 1 (sqrt(+ (square x) (square y))) (monte-carlo-sampling(- n 1)))) 
      ))))) 
+0

Итак, что вы подразумеваете под словом "it does not work" – Blorgbeard

ответ

1

Я написал решение этой проблемы на моем blog; внутренняя функция называется sand, потому что я бросал зерно песка вместо мрамора:

(define (pi n) 
    (define (sand?) (< (+ (square (rand)) (square (rand))) 1)) 
    (do ((i 0 (+ i 1)) (p 0 (+ p (if (sand?) 1 0)))) 
     ((= i n) (exact->inexact (* 4 p (/ n)))))) 

Это сходится очень медленно; после сто тысяч итераций у меня было 3.14188. В записи в блоге также обсуждается метод оценки pi, разработанный Архимедом более двухсот лет до Рождества Христова, который сходится очень быстро, причем 27 итераций ведут нас к пределу арифметики с двойной точностью.

2

Ваши скобки все испорчены, и ваш аргумент для < неверен. Вот как выглядит код после его исправления:

(define (monte-carlo-sampling n) 
    (let ((x (- (* 2 (random)) 1)) 
     (y (- (* 2 (random)) 1))) 
    (cond ((= n 0) 
      0) 
      (else 
      (cond ((< (sqrt (+ (square x) (square y))) 1) 
        (+ 1 (monte-carlo-sampling (- n 1)))) 
       (else 
        (monte-carlo-sampling (- n 1)))))))) 

Это возвращает количество просмотров. Вы должны были бы преобразовать число попаданий в оценке пи, используя внешнюю функцию, например:

(define (estimate-pi n) 
    (* 4 (/ (monte-carlo-sampling n) n))) 

Вот как я пишу все это, если бы это было до меня:

(define (estimate-pi n) 
    (let loop ((i 0) 
      (hits 0)) 
    (cond ((>= i n) 
      (* 4 (/ hits n))) 
      ((<= (hypot (sub1 (* 2 (random))) 
         (sub1 (* 2 (random)))) 1) 
      (loop (add1 i) (add1 hits))) 
      (else 
      (loop (add1 i) hits))))) 

(Проверено на рэкет, используя определение hypot я дал в своем последнем ответе. Если вы не используете рэкет, вы должны изменить add1 и sub1 на что-то подходящее.)

0

Вот общий способ делать Монте-Карло он принимает в качестве аргументов число итераций, и преобразователь (процедура без аргументов), которые должны возвращать #t или #f что эксперимент для запуска каждой итерации

(define (monte-carlo trials experiment) 
    (define (iter trials-remaining trials-passed) 
    (cond ((= trials-remaining 0) 
      (/ trials-passed trials)) 
      ((experiment) 
      (iter (- trials-remaining 1) (+ trials-passed 1))) 
      (else 
      (iter (- trials-remaining 1) trials-passed)))) 
    (iter trials 0)) 

Теперь это просто матер писать конкретный эксперимент

Вы могли бы написать в эксперименте, где эксперимент вызывается в Монте-Карло, но абстрагируясь здесь дает гораздо более гибкой и понятной функции. Если вы выполняете функцию, слишком много вещей сразу становится трудно рассуждать и отлаживать.

(define (marble-experiment) 
(let ((x ...) ;;assuming you can come up with 
     (y ...)) ;;a way to get a random x between 0 and 1 
       ;;with sufficient granularity for your estimate) 
    (< (sqrt (+ (* x x) (* y y))) 1))) 

(define pi-estimate 
    (* 4 (monte-carlo 1000 marble-experiment))) 

 Смежные вопросы

  • Нет связанных вопросов^_^