Идея метода Монте-Карло

Иногда самый честный способ узнать ответ — не вывести формулу, а много раз подбросить монетку и посмотреть, что получится в среднем.

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

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

Зачем вообще бросать кости

В школьной математике мы привыкли, что у каждой задачи есть «правильное» решение — формула, в которую подставляешь числа и получаешь точный ответ. Но реальный мир устроен сложнее. Площадь фигуры может не выражаться через элементарные функции. Вероятность сложного события — складываться из десятков пересекающихся условий. Поведение системы — зависеть от тысяч случайных факторов сразу. В таких случаях аналитическое решение либо невозможно, либо настолько громоздко, что проще его не искать.

Метод Монте-Карло предлагает обходной манёвр. Вместо того чтобы выводить ответ, мы его измеряем — ставим вычислительный эксперимент. Разыгрываем случайные исходы много-много раз и смотрим, какая доля из них удовлетворяет нужному условию. По закону больших чисел эта доля при росте числа испытаний сходится к истинной вероятности, а среднее — к математическому ожиданию. Компьютер бросает «кости» миллионы раз в секунду, поэтому то, что человеку было бы непосильно вручную, машина делает за доли мгновения.

Немного истории: бомба, нейтроны и казино

Название у метода почти легендарное. В конце 1940-х годов математик Станислав Улам, работая в Лос-Аламосе над атомным проектом, размышлял над задачей: какова вероятность, что нейтрон, блуждая внутри вещества, в итоге вызовет цепную реакцию? Траектория нейтрона зависит от множества случайных столкновений, и честная формула не выводилась. Улам предложил идею: смоделировать множество случайных «судеб» отдельных нейтронов и посчитать, какая доля привела к нужному исходу.

Идею подхватил Джон фон Нейман, и метод стал секретным инструментом расчётов. Кодовое имя ему придумали под стать эпохе: дядя Улама любил играть в казино города Монте-Карло в Монако, а казино — это и есть храм случайности и больших чисел. Так за методом и закрепилось имя Monte Carlo. С тех пор он разошёлся далеко за пределы физики: финансы, биология, компьютерная графика, искусственный интеллект — везде, где приходится иметь дело с неопределённостью.

Классический пример: оцениваем число π

Лучший способ почувствовать метод — оценить им что-нибудь известное, чтобы можно было проверить ответ. Возьмём число π. Впишем четверть круга единичного радиуса в единичный квадрат и будем бросать в этот квадрат случайные точки. Площадь квадрата равна 1, площадь четверти круга равна π/4. Значит, доля точек, попавших внутрь четверти круга, в среднем равна π/4. Умножив эту долю на 4, мы получим оценку самого π.

Точка (x, y) лежит внутри четверти круга, если её расстояние до начала координат не превышает 1, то есть когда x*x + y*y <= 1. Вот и весь критерий.

import random
random.seed(42)
inside = 0
N = 100000
for _ in range(N):
    x = random.random()
    y = random.random()
    if x*x + y*y <= 1.0:
        inside += 1
pi_est = 4 * inside / N
print(f"Бросков: {N}")
print(f"Внутри круга: {inside}")
print(f"Оценка пи: {pi_est:.5f}")
print(f"Ошибка: {abs(pi_est - 3.141592653589793):.5f}")

Вывод:

Бросков: 100000
Внутри круга: 78432
Оценка пи: 3.13728
Ошибка: 0.00431

Сто тысяч случайных точек дали π с точностью до второго знака — без единой формулы для окружности, только подсчётом доли попаданий. Обратите внимание на строку random.seed(42): она фиксирует генератор случайных чисел так, чтобы при каждом запуске выпадала одна и та же последовательность. Это называется seed (зерно), и для воспроизводимости учебных примеров он незаменим — у вас на экране получатся ровно те же 78432 попадания.

Когда метод применять

Монте-Карло — не универсальная замена математике, а инструмент для конкретного класса ситуаций. Вот когда он по-настоящему уместен.

СитуацияПочему помогает Монте-Карло
Нет аналитической формулыНе нужно её выводить — достаточно уметь разыграть один исход
Сложная геометрия областиБросаем точки и считаем долю попавших, форма границы неважна
Многомерная задачаСложность почти не растёт с числом измерений
Запутанная вероятностьСимулируем событие тысячи раз вместо разбора всех случаев

Как работает под капотом

В основе всего лежит закон больших чисел. Пусть у каждого испытания есть два исхода — «удача» (точка попала в круг) и «неудача». Обозначим истинную вероятность удачи за p. Каждое отдельное испытание случайно: иногда удача, иногда нет. Но если провести N независимых испытаний и посчитать долю удач k/N, то по закону больших чисел эта доля при росте N неограниченно приближается к p.

В нашем коде p = π/4. Каждый виток цикла — одно испытание: генерируем точку, проверяем условие x*x + y*y <= 1.0, при попадании увеличиваем счётчик inside. После N бросков inside/N — это и есть оценка p, а умножение на 4 переводит её в оценку π. Генератор random.random() выдаёт числа, равномерно распределённые на отрезке от 0 до 1, поэтому точки ложатся в квадрат без перекосов — это критично, иначе доля исказится.

Схематически процесс выглядит так:

случайная точка (x, y)
        |
        v
   x*x + y*y <= 1 ?
   /            \
 да             нет
  |              |
inside += 1   пропускаем
        \      /
         v    v
 после N бросков:  4 * inside / N --> оценка π

Частые ошибки

  • Забыть про random.seed(...) и удивляться, что результат каждый раз чуть другой. Случайность — это нормально, но для воспроизводимости примеров seed обязателен.
  • Ждать абсолютно точного ответа. Метод даёт приближение: даже на 100000 бросков остаётся ошибка в третьем знаке. Точное π так не получить никогда.
  • Брать слишком мало испытаний. На сотне точек оценка π скачет от 2.9 до 3.4 — выводам доверять рано.
  • Использовать неравномерный или некачественный генератор. Если точки ложатся в квадрат с перекосом, доля попаданий исказится и оценка «уедёт».
  • Путать долю и количество: оценка вероятности — это inside/N, а не сам inside.

Итоги

  • Метод Монте-Карло заменяет аналитический вывод множеством случайных испытаний и оценкой доли или среднего.
  • Работает он благодаря закону больших чисел: доля удач сходится к истинной вероятности при росте числа бросков.
  • Назван в честь казино Монте-Карло, а родился из задачи о блуждании нейтронов в атомном проекте (Улам, фон Нейман).
  • Оценка π через точки в круге — канонический пример: доля попаданий в четверть круга равна π/4.
  • Применять метод стоит там, где формулы нет, геометрия сложна, размерность велика или вероятность запутана.
  • Ответ всегда приближённый; для воспроизводимости фиксируйте генератор через seed.
Проверьте себя
1. На чём основан метод Монте-Карло?
AНа точном аналитическом выводе формулы
BНа законе больших чисел: доля удачных испытаний сходится к истинной вероятности
CНа округлении промежуточных результатов
DНа сортировке случайных чисел по возрастанию
2. Почему в примере доля точек, попавших в четверть круга, умножается на 4?
AПотому что у квадрата четыре стороны
BПотому что площадь четверти круга равна π/4, а площадь квадрата равна 1
CПотому что бросков было кратно четырём
DПотому что радиус круга равен 4
3. Зачем в коде вызывается random.seed(42)?
AЧтобы ускорить генерацию случайных чисел
BЧтобы сделать последовательность случайных чисел воспроизводимой при каждом запуске
CЧтобы получить ровно 42 случайные точки
DЧтобы повысить точность оценки π