
3.1. Присваивание и внутреннее состояние объектов
221
Упражнение 3.5.
Интегрирование методом Монте-Карло (Monte Carlo integration) — способ приближенного вы-
числения определенных интегралов при помощи моделирования методом Монте-Карло. Рассмот-
рим задачу вычисления площади фигуры, описываемой предикатом P (x, y), который истинен для
точек (x, y), принадлежащих фигуре, и ложен для точек вне фигуры. Например, область, содер-
жащаяся в круге с радиусом 3 и центром в точке (5, 7), описывается предикатом, проверяющим
(x −5)
2
+ (y −7)
2
≤ 3
2
. Чтобы оценить площадь фигуры, описываемой таким предикатом, для на-
чала выберем прямоугольник, который содержит нашу фигуру. Например, прямоугольник с углами
(2, 4) и (8, 10), расположенными по диагонали, содержит вышеописанный круг. Нужный нам ин-
теграл — площадь той части прямоугольника, которая лежит внутри фигуры. Мы можем оценить
интеграл, случайным образом выбирая точки (x, y), лежащие внутри прямоугольника, и проверяя
для каждой точки P (x, y), чтобы определить, лежит ли точка внутри фигуры. Если мы проверим
много точек, доля тех, которые окажутся внутри области, даст нам приближенное значение отно-
шения площадей фигуры и прямоугольника. Таким образом, домножив это значение на площадь
прямоугольника, мы получим приближенное значение интеграла.
Реализуйте интегрирование методом Монте-Карло в виде процедуры estimateintegral, ко-
торая в качестве аргументов принимает предикат P, верхнюю и нижнюю границы прямоугольника
x1, x2, y1 и y2, а также число проверок, которые мы должны осуществить, чтобы оценить отноше-
ние площадей. Ваша процедура должна использовать ту же самую процедуру monte-carlo, кото-
рая выше использовалась для оценки значения π. Оцените π при помощи estimate-integral,
измерив площадь единичного круга.
Вам может пригодиться процедура, которая выдает число, случайно выбранное внутри данного
отрезка. Нижеприведенная процедура random-in-range решает эту задачу, используя процедуру
random, введенную в разделе 1.2.6, которая возвращает неотрицательное число меньше своего
аргумента
8
.
(define (random-in-range low high)
(let ((range (- high low)))
(+ low (random range))))
Упражнение 3.6.
Полезно иметь возможность с бросить генератор случайных чисел, чтобы получить последова-
тельность, которая начинается с некоторого числа. Постройте новую процедуру rand, которая
вызывается с аргументом. Этот аргумент должен быть либо символом generate, либо симво-
лом reset. Процедура работает так: (rand ’generate) порождает новое случайное число;
((rand ’reset) hновое-значениеi) сбрасывае т внутреннюю переменную состояния в ука-
занное hновое-значениеi. Таким образом, сбрасывая значения, можно получать повторяющиеся
последовательности. Эта возможность очень полезна при тестировании и отладке программ, ис-
пользующих случайные числа.
3.1.3. Издержки, связанные с введением присваивания
Как мы только что видели, операция set! позволяет моделировать объекты, облада-
ющие внутренним состоянием. Однако за это преимущество приходится платить. Наш
язык программирования нельзя больше описывать при помощи подс тановочной модели
8
В MIT Scheme есть такая процедура. Е сли random на вход дается точное целое число (как в разделе 1.2.6),
она возвращает точное целое число, но если ей дать десятичную дробь (как в этом примере), она и возвращает
десятичную дробь.