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

⏱ 40 мин · 🧩 заданий: 6

Интеграл как среднее

Вспомним: среднее значение функции \bar f = \frac{1}{b - a}\int_a^b f\,dx. Если X — случайная точка, равномерно распределённая на [a; b], то E f(X) = \bar f. По закону больших чисел среднее по многим случайным точкам приближается к математическому ожиданию:

\int_a^b f(x)\,dx \approx \frac{b - a}{N}\sum_{i=1}^N f(X_i).

Это метод Монте-Карло (назван в честь казино; придуман Уламом и фон Нейманом в Лос-Аламосе в 1940-х).

Метод попаданий

Площадь фигуры D внутри прямоугольника площади A: бросаем N случайных точек в прямоугольник, считаем, сколько попало в D:

S(D) \approx A\cdot\frac{N_{\text{попаданий}}}{N}.

Вычисление \pi: четверть круга в квадрате [0; 1]^2 имеет площадь \frac\pi4.

import numpy as np
import vis

rng = np.random.default_rng(0)
x, y = rng.random(2000), rng.random(2000)
inside = x**2 + y**2 <= 1
print("π ≈", 4 * inside.mean(), "по 2000 точкам")
vis.scatter(x, y, labels=inside.astype(int), title="Точки внутри четверти круга (оранжевые) и вне её", equal=True)

for N in [10**2, 10**3, 10**4, 10**5, 10**6]:
    p = (rng.random(N)**2 + rng.random(N)**2 <= 1).mean()
    print(f"N = {N:>8}: π ≈ {4 * p:.5f}, ошибка {abs(4 * p - np.pi):.5f}")

Ошибка \sim\frac{1}{\sqrt N}

По центральной предельной теореме ошибка оценки примерно нормальна со стандартным отклонением

\sigma_N = (b - a)\frac{\sigma_f}{\sqrt N},

где \sigma_f — стандартное отклонение f(X). Это значит:

  • чтобы получить ещё один верный знак, нужно в 100 раз больше точек — в одномерном случае это очень медленно (Симпсон: в 10^{1/4} \approx 1{,}8 раза);
  • ошибка не зависит от размерности! Для интеграла по 100-мерному кубу скорость та же.

Ошибку можно оценить по самой выборке: \sigma_f \approx s (выборочное отклонение). С вероятностью ≈95% истинное значение лежит в интервале \pm2\sigma_N.

import numpy as np
from math import gamma, pi

rng = np.random.default_rng(42)
# Объём единичного шара в размерности d: доля точек куба [−1, 1]^d внутри шара, умноженная на 2^d
for d in [2, 3, 5, 8, 10]:
    N = 400000
    pts = rng.uniform(-1, 1, size=(N, d))
    hit = (np.sum(pts**2, axis=1) <= 1)
    est = 2**d * hit.mean()
    se = 2**d * hit.std() / np.sqrt(N)
    exact = pi**(d / 2) / gamma(d / 2 + 1)
    print(f"d = {d:2}: V ≈ {est:.4f} ± {2 * se:.4f}   (точно {exact:.4f})")

С ростом размерности доля попаданий падает (шар занимает всё меньшую часть куба), и относительная ошибка растёт — сказывается \sigma_f. Это лечится умными способами выбора точек.

Как уменьшить дисперсию

  • Выборка по значимости: точки бросают гуще там, где |f| велико, и делят на плотность: \int f\,dx = E\frac{f(Y)}{p(Y)}, Y \sim p. При p \approx \frac{|f|}{\int|f|} дисперсия почти нулевая.
  • Стратификация: делим отрезок на части и в каждую бросаем поровну точек.
  • Квазислучайные последовательности (Соболя, Холтона) заполняют пространство равномернее случайных; ошибка близка к \frac1N вместо \frac{1}{\sqrt N}.

Монте-Карло — рабочая лошадка физики частиц, финансовой математики (цены опционов — многомерные интегралы), компьютерной графики (трассировка лучей считает интегралы освещённости) и байесовской статистики.

Итог

  • \int_a^b f\,dx \approx (b - a)\cdot\overline{f(X_i)} по случайным точкам; площади — долей попаданий.
  • Ошибка \sim\frac{\sigma_f}{\sqrt N} и не зависит от размерности — Монте-Карло незаменим для многомерных интегралов.
  • Дисперсию уменьшают выборкой по значимости, стратификацией и квазислучайными точками.

Практика решено 0 из 6

Вы не вошли — ответы проверяются, но прогресс не сохранится. Войти или зарегистрироваться.
Задание 1 Ввод формулы

Случайные точки равномерно бросают в квадрат [0;\,1]^2. Какая доля в среднем попадёт под график y = x^2?

Как вводить формулы Степень — ^ (x^2, e^(3x)), умножение можно не писать (2x, x sin(x)), дробь — / (1/(x+1)), корень — sqrt(x), модуль — |x| или abs(x). Функции: sin cos tg ctg arcsin arccos arctg arcctg sh ch ln lg exp, константы pi и e. Аргументы функций лучше брать в скобки: sin(2x). Для неопределённого интеграла допишите + C. Индексы пишутся слитно: m1, v0; греческие буквы — словом или символом: alpha или α. Десятичная дробь — через точку или запятую, большие числа — через 10^: 6,67*10^(-11).
Задание 2 Ввод формулы

Доля точек квадрата [-1;\,1]^2, попавших в единичный круг, — p. Выразите \pi через p: \pi = \;?

Как вводить формулы Степень — ^ (x^2, e^(3x)), умножение можно не писать (2x, x sin(x)), дробь — / (1/(x+1)), корень — sqrt(x), модуль — |x| или abs(x). Функции: sin cos tg ctg arcsin arccos arctg arcctg sh ch ln lg exp, константы pi и e. Аргументы функций лучше брать в скобки: sin(2x). Для неопределённого интеграла допишите + C. Индексы пишутся слитно: m1, v0; греческие буквы — словом или символом: alpha или α. Десятичная дробь — через точку или запятую, большие числа — через 10^: 6,67*10^(-11).

Обозначения в ответе: p.

Задание 3 Ввод формулы

Ошибка Монте-Карло убывает как \frac{1}{\sqrt N}. Во сколько раз нужно увеличить число точек, чтобы ошибка уменьшилась в 10 раз?

Как вводить формулы Степень — ^ (x^2, e^(3x)), умножение можно не писать (2x, x sin(x)), дробь — / (1/(x+1)), корень — sqrt(x), модуль — |x| или abs(x). Функции: sin cos tg ctg arcsin arccos arctg arcctg sh ch ln lg exp, константы pi и e. Аргументы функций лучше брать в скобки: sin(2x). Для неопределённого интеграла допишите + C. Индексы пишутся слитно: m1, v0; греческие буквы — словом или символом: alpha или α. Десятичная дробь — через точку или запятую, большие числа — через 10^: 6,67*10^(-11).
Задание 4 Ввод формулы

Оценка \int_0^2 f\,dx \approx 2\cdot\bar f, где \bar f — среднее значение f в случайных точках. Для f(x) = x и точек 0{,}3;\,1{,}1;\,1{,}8;\,0{,}6 вычислите оценку.

Как вводить формулы Степень — ^ (x^2, e^(3x)), умножение можно не писать (2x, x sin(x)), дробь — / (1/(x+1)), корень — sqrt(x), модуль — |x| или abs(x). Функции: sin cos tg ctg arcsin arccos arctg arcctg sh ch ln lg exp, константы pi и e. Аргументы функций лучше брать в скобки: sin(2x). Для неопределённого интеграла допишите + C. Индексы пишутся слитно: m1, v0; греческие буквы — словом или символом: alpha или α. Десятичная дробь — через точку или запятую, большие числа — через 10^: 6,67*10^(-11).
Задание 5 Один вариант ответа

Почему для интеграла по 20-мерному кубу Монте-Карло лучше метода Симпсона?

Задание 6 Программа на Python

Монте-Карло с доверительным интервалом. Напишите функцию mc(f, a, b, n, seed=0): сгенерируйте n равномерных точек на [a; b] генератором random.Random(seed), верните пару (оценка, стандартная_ошибка), где оценка = (b - a)\bar f, а стандартная ошибка = (b - a)\frac{s}{\sqrt n}, s — выборочное стандартное отклонение значений f (делите на n - 1).

Какие тесты проверяют код (1)
import math
val, se = mc(lambda x: 5.0, 0, 2, 100)
assert abs(val - 10) < 1e-12 and se < 1e-12, "Для константы ошибка нулевая"
val, se = mc(math.sin, 0, math.pi, 20000, seed=1)
assert abs(val - 2) < 4 * se, "Ответ должен попасть в доверительный интервал"
assert 0.005 < se < 0.02, f"Стандартная ошибка для N = 20000 около 0,01, у вас {se}"
v1, s1 = mc(math.exp, 0, 1, 1000, seed=3)
v2, s2 = mc(math.exp, 0, 1, 16000, seed=3)
assert 3 < s1 / s2 < 5, "При увеличении N в 16 раз ошибка уменьшается примерно в 4 раза"

Войдите, чтобы отмечать пройденные уроки.