Метод Монте-Карло в Python

Я пытался использовать Python для создания скрипта, который позволяет мне генерировать большое количество точек для использования в методе Монте-Карло для вычисления оценки числа Пи. Сценарий, который у меня есть, таков:

import math
import random
random.seed()

n = 10000

for i in range(n):
    x = random.random()
    y = random.random()
    z = (x,y)

    if x**2+y**2 <= 1:
        print z
    else:
        del z

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


person Matt Johnson    schedule 19.11.2012    source источник
comment
Вы хотите посчитать, сколько случайных пар находится внутри круга? Если это так, просто используйте счетчик ...   -  person zenpoy    schedule 20.11.2012


Ответы (3)


Если вы выполняете какие-либо тяжелые численные вычисления, подумайте об обучении numpy. Ваша проблема по сути однолинейная с настройкой numpy:

import numpy as np

N   = 10000
pts = np.random.random((N,2))

# Select the points according to your condition
idx = (pts**2).sum(axis=1)  < 1.0
print pts[idx], idx.sum()

Раздача:

[[ 0.61255615  0.44319463]
 [ 0.48214768  0.69960483]
 [ 0.04735956  0.18509277]
 ..., 
 [ 0.37543094  0.2858077 ]
 [ 0.43304577  0.45903071]
 [ 0.30838206  0.45977162]], 7854

Последнее число - это количество подсчитанных событий, то есть количество точек, радиус которых меньше единицы.

person Hooked    schedule 19.11.2012

Не уверен, что это то, что вы ищете, но вы можете запустить enumerate на range и получить позицию в своей итерации:

In [1]: for index, i in enumerate(xrange(10, 15)):
   ...:     print index + 1, i
   ...:
   ...:
1 10
2 11
3 12
4 13
5 14

В этом случае index + 1 будет представлять текущую создаваемую точку (сам index будет общим количеством точек, созданных в начале данной итерации). Кроме того, если вы используете Python 2.x, xrange обычно лучше подходит для такого рода итераций, поскольку он не загружает весь список в память, а, скорее, обращается к нему по мере необходимости.

person RocketDonkey    schedule 19.11.2012
comment
@ahans Нет проблем - я помню, как впервые увидел это и подумал: «А, подумал, есть способ сделать это». Получайте удовольствие от его использования! - person RocketDonkey; 20.11.2012

Просто добавьте переменную hits перед циклом, инициализируйте ее значением 0 и внутри оператора if увеличивайте hits на единицу.
Наконец, вы можете рассчитать значение PI, используя совпадения и n.

import math
import random
random.seed()

n = 10000
hits = 0  # initialize hits with 0

for i in range(n):
    x = random.random()
    y = random.random()
    z = (x,y)

    if x**2+y**2 <= 1:
        hits += 1
    else:
        del z

# use hits and n to compute PI
person pm007    schedule 19.11.2012