Оценка числа π методом Монте-Карло
Считаем геометрическую константу, бросая случайные точки — классика метода Монте-Карло.
Метод Монте-Карло оценивает числовую величину через долю случайных точек, попавших в нужную область.
Случайность умеет не только моделировать игры, но и вычислять. Самый наглядный пример — оценка числа $\pi$ без единой формулы геометрии: достаточно бросать точки в квадрат и считать, сколько попало в четверть круга. Этот приём масштабируется до задач, где обычные методы бессильны. Идея вычислять детерминированную величину через случайность поначалу кажется странной — при чём тут случай, если $\pi$ — фиксированное число? Но в этом и красота метода: мы не угадываем $\pi$, а измеряем его, как измеряют площадь поля, бросая зёрна и считая, сколько упало внутрь разметки. Чем больше зёрен, тем точнее измерение. Этот же принцип позволяет физикам считать поведение частиц, финансистам — оценивать стоимость опционов, а художникам по компьютерной графике — рассчитывать реалистичное освещение: всюду, где честный перебор невозможен, на помощь приходит «бросание зёрен». Оценка $\pi$ — самая наглядная витрина метода, на которой удобно понять и его силу, и его ограничения.
Геометрическая идея
Рассмотрим квадрат $[0;1]\times[0;1]$ и четверть единичного круга внутри него. Площадь квадрата равна $1$, площадь четверти круга — $\frac{\pi}{4}$. Если бросать точки равномерно, доля попавших в круг стремится к отношению площадей:
$$\frac{\text{точек в круге}}{\text{всего точек}}\to\frac{\pi}{4}\quad\Rightarrow\quad \pi\approx 4\cdot\frac{\text{точек в круге}}{\text{всего точек}}.$$
Точка $(x,y)$ лежит в четверти круга, если $x^2+y^2\le 1$. Проверим.
import random
random.seed(33)
def estimate_pi(n):
inside = 0
for _ in range(n):
x, y = random.random(), random.random()
if x*x + y*y <= 1.0:
inside += 1
return 4 * inside / n
for n in [1000, 10000, 100000, 1000000, 5000000]:
print(f"n={n:>7}: pi ≈ {estimate_pi(n):.5f}")
print("Истинное: 3.14159")Вывод:
n= 1000: pi ≈ 3.20000 n= 10000: pi ≈ 3.13680 n= 100000: pi ≈ 3.14584 n=1000000: pi ≈ 3.14117 n=5000000: pi ≈ 3.14210 Истинное: 3.14159
С ростом числа точек оценка ползёт к $3{,}14159$. Уже на миллионе точек мы угадываем три-четыре знака.
Точность и её цена
Точность Монте-Карло подчиняется тому же закону $1/\sqrt{n}$, что и частота: типичная ошибка оценки убывает как
$$\text{ошибка}\sim\frac{C}{\sqrt{n}}.$$
Это значит, что для лишнего верного знака (точность в 10 раз выше) нужно в 100 раз больше точек. Поэтому Монте-Карло — не лучший способ считать $\pi$ (есть ряды, сходящиеся куда быстрее), но он бесценен там, где область сложна и аналитика невозможна.
Почему метод вообще работает
За кулисами здесь снова закон больших чисел: индикатор «точка в круге» — бернуллиевская величина с вероятностью успеха $\frac{\pi}{4}$. Доля успехов сходится к этой вероятности, а умножение на 4 даёт $\pi$. То есть оценка $\pi$ — это оценка математического ожидания индикатора, замаскированная под геометрию.
Как работает под капотом
Каждая итерация генерирует точку равномерно в квадрате двумя вызовами random.random() и проверяет неравенство $x^2+y^2\le 1$ — то есть попадание в круг. Счётчик inside накапливает успехи, а формула $4\cdot\text{inside}/n$ превращает долю площади в оценку $\pi$. Никакого знания о $\pi$ в коде нет — оно «извлекается» из геометрии круга через случайные точки. Чем больше точек, тем точнее доля, и тем ближе оценка к истине.
Частые ошибки
Первая ошибка — забыть множитель 4: доля точек даёт $\frac{\pi}{4}$, а не сам $\pi$. Вторая — ждать высокой точности при малом $n$: на тысяче точек разброс в сотых долях нормален, это не ошибка кода. Третья — использовать неравномерный генератор точек: если точки не равномерны в квадрате, отношение площадей нарушится и оценка будет смещённой. Метод требует именно равномерности.
Итог
- Доля случайных точек в четверти круга стремится к $\frac{\pi}{4}$.
- Отсюда $\pi\approx 4\cdot(\text{доля точек в круге})$.
- Точность растёт как $1/\sqrt{n}$: лишний знак стоит в 100 раз больше точек.
- За методом стоит закон больших чисел для индикатора попадания.