2013-08-17 3 views
1

Я пытался создать эксперимент иглы Buffoon через упрощенный способ использования случайности в качестве замены вероятности. Значение pi можно найти из уравнения pi = 2 * ln/th, где l = длина иглы, n = количество раз, когда игла опускается, t = ширина линий, h = количество раз, когда игла пересекает линию , Я предположил, что l = t, тем самым уменьшая мое уравнение до pi = 2 * n/h. Теперь я сделал два кода. Код 1:Речь идет о случайном выборе в python

import math, random 
h = 0.0 
n = 0.0 
for i in range(0,10000): 
    a = random.random() 
    if a > 0.64: 
     h = h+1 
    else: 
     n = n+1 
re = 2*(n+h)/n 
print "Value of pi is ", re 
err = (math.pi - re)*100/(math.pi) 
print "Percentage error is ", abs(err) 

Теперь это один работает нормально и дает мне достаточно хорошие результаты. Но следующий код повторяет один и тот же ответ снова и снова. Код 2:

import random, time, math 
h=1.0 
n=1.0 
err = 0.0 
while err < 0.1: 
    a = random.random() 
    if a > 0.64: 
     h = h+1 
    else: 
     n = n+1 
    re = 2*(n+h)/n 
    err = (math.pi - re)*100/(math.pi) 
print "Number of attempts is ", n+h 

Может кто-нибудь сказать мне, почему ??

+1

Не то, что он отвечает на ваш вопрос, но ваша программа, в обоих случаях приблизительно 2/0,64, а не Пи. Он не имеет ничего общего с иглой Буффона. –

ответ

0

Ваш while Состояние петли - назад. Оно должно быть:

while err > 0.1: 

Вы должны также установить err в 1.0 или что-то выше, чем 0.1.

Наконец, при расчете ошибки, вы должны использовать abs:

err = abs(math.pi - re)/(math.pi) 
+0

Привет Блендер и Антти Хаапала за ваши предложения. Теперь код работает нормально. У меня больше проблем, которые я буду публиковать в ближайшее время. Еще раз спасибо. –

0

Вы хотите ошибка быть как можно больше в начале, а затем цикл до тех пор, пока не станет достаточно малым. Используйте

import sys 

error = sys.float_info.max 
epsilon = 0.1 
while err > epsilon: 
    ... 

Кроме того, как правило, разница может быть отрицательной тоже, поэтому, чтобы получить ошибку вы хотите использовать абс только сравнить величину. Таким образом, мы получаем более идиоматической программу

import random, time, math 
import sys 

h = n = 1.0 
err = sys.float_info.max 
epsilon = 0.001 

while err > epsilon: 
    a = random.random() 
    if a > 0.64: 
     h += 1 
    else: 
     n += 1 

    re = 2 * (n + h)/n 
    err = abs((math.pi - re)/math.pi) 

print "Value of pi is ", re 
print "Number of attempts is ", n + h 
+0

Хорошо. Я попробую и посмотрю. Благодарю. –

+1

Нет необходимости в 'sys.float_info.max' просто использовать 'float ('+ inf')'. – Bakuriu

+0

... хотя они не то же самое, но здесь это работает. –

0

другие отмечали проблемы с остановочными критериями, но ваш код имеет более фундаментальный недостаток. Это NOT Эксперимент с иглой Буффона. Вы нашли слегка запутанный способ расчета отношения 2,0/0,64. Если вы неоднократно запускали свою программу и усредняли результаты, вы бы обнаружили, что среднее число сходится к 3.125, а не к Pi. Эксперимент Буффона основывался на том, пересекла ли игла ни одна из параллельных линий, основанная как на местоположении центра иглы, так и на углу падения, ни один из которых не учитывается в вашей программе.

Если вы хотите относительно простой способ Монте-Карло оценить Pi, произвольно создавайте точки по квадрату 2x2 с центром в (0,0) и посмотрите, какая доля этих точек попадает в вписанную окружность с единичным радиусом. Эта пропорция должна быть такой же, как соотношение двух областей, Pi/4, поэтому умножение оценочной доли на 4 дает достойную оценку Pi. В псевдокоде:

count = 0 
repeat N times 
    x <- U(-1,1) 
    y <- U(-1,1) 
    if x^2 + y^2 <= 1 
    increment count 
pi_est <- 4 * count/N 

где U(-1,1) указывает генерировать значение равномерно между -1 и 1.

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