Моделирование методом Монте-Карло пришло к нам из в 1930—1940 гг., когда физики на компьютере моделировали ситуации для оценки вероятности того, что цепная реакция, необходимая для атомной бомбы, пройдет успешно. Учёные, участвовавшие в этой работе, были страстными поклонниками азартных игр, они и дали операциям моделирования такое название. Метод статистического моделирования Монте-Карло назван так в честь столицы княжества Монако, известной своими многочисленными казино, основанные на законах распределения случайных величин.
Рассмотрим произвольный квадрат с центром в начале координат и вписанный в него круг. Будем рассматривать только первую координатную четверть.
Будем случайным образом выбирать точки в этом квадрате и считать количество точек, попавших в четверть круга. Благодаря теории вероятности мы знаем, что отношение попаданий в круг к числу всех точек равно отношению площадей. Вот, собственно, и весь алгоритм... Чем больше взятых наугад точек мы проверим, тем точнее будет отношение площадей. Ограничиваем количество выбранных точек производительностью компьютера.
program METOD_MONTEKARLO;
uses crt;
var r,x,y,m,n,i:integer;
s:real;
begin
randomize;
writeln ('введите радиус R');
readln (r);
m:=0;
n:=100000;
for i:=1 to n do
begin
x:=random(2*r+1)-r;
y:=random(2*r+1)-r;
if x*x+y*y<=r*r then m:=m+1
end;
writeln('всего точек попавших в круг - ',m);
s:=4*r*r*m/n;
writeln('аналитически - ',s:0:3);
writeln ('вычисленная - ',pi*r*r:0:3);
end.
Пример 2.
Найти площадь пересечения трех окружностей с заданными радиусами и координатами центров окружностей.
Аналитические выкладки для определения площади пересечения невозможен. Метод Монте-Карло позволяет приближенно вычислить площадь, даже в том случае, когда имеется лишь возможностью определить, принадлежит ли точка данной области.
Составим модель. Опишем квадрат около первой, для определённости, окружности. Будем случайным образом кидать точки в этот квадрат. При достаточно большом их количестве они равномерно распределятся по площади квадрата. Часть из них попадет в область пересечения трех окружностей. Как и в предыдущей задаче отношение m/n равен отношению искомой площади к площади описанного квадрата.
uses crt;
label
NotInCircle;
var
i, n, m: LongInt;
j: Integer;
x, y, r, rr: array[1..3] of Real;
xp, yp, xkv, ykv, d: Real;
begin
for j:=1 to 3 do
begin
writeln('Введите координаты центра и радиус ', j, '-й окружности (x, y и r)' );
Write();
ReadLn(x[j], y[j], r[j]);
rr[j]:=Sqr(r[j]); // квадраты радиусов
end;
Writeln('Введите число брошенных точек в квадрат '); ReadLn(n);
xkv:=x[1]- r[1]; //квадрат около окружности
ykv:=y[1]- r[1];
d:=r[1]*2;
m:=0;
Randomize;
for i:=1 to n do // цикле по числу бросаний
begin
xp:=Random*d+xkv;
yp:=Random*d+ykv; // случайные точки (х,у) брошенные в квадрат описываемый первую окружность
for j:=1 to 3 do
if Sqr(xp-x[j])+Sqr(yp-y[j]) > rr[j] then goto NotInCircle; //проверяем, попадает ли точка в каждый круг
Inc(m); // подсчёт количества точек, попавших сразу во все три круга
NotInCircle:
end;
writeln('количество точек, попавших сразу во все три круга ',m );
WriteLn('S = ', Sqr(d)*m/n:0:3); {результат, тем точнее, чем больше историй}
end.
|