Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Tyutterin_Yakov_Z1411_with_1_and_2

.pdf
Скачиваний:
0
Добавлен:
07.01.2025
Размер:
5.51 Mб
Скачать

51

Задание на выполнение этапа №2. Исследование метода Монте-Карло для вычисления площадей плоских фигур

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

Суть метода заключается в следующем:

1. Процесс описывается математической моделью с использованием генератора случайных величин. 2. Модель многократно обсчитывается. 3. На основе полученных данных вычисляются вероятностные характеристики рассматриваемого процесса.

Методы используются для решения задач в различных областях физики, химии, математики, экономики, оптимизации, теории управления и др.

В качестве примера описания работы алгоритма возьмем вычисление числа Pi.

Число Пи – это отношение длины окружности к диаметру этой окружности. Независимо от размера любого круга, значение числа пи приблизительно равно 3,14159. Она применима при вычислениях, касающихся кругов.

Число Пи – иррациональное число, его нельзя выразить простой дробью или определенной десятичной дробью. Мы можем вычислить число пи с любым желаемым уровнем точности, используя различные математические методы.

Начнем с того, что метод Монте-Карло является одним из методов, используемых для оценки значения числа pi. Этот метод использует случайную выборку для получения численного решения математических задач.

Например, давайте предположим, что у нас есть пустой холст. Затем давайте нарисуем квадрат на холсте и большой круг внутри квадрата. Затем давайте сгенерируем случайные точки внутри квадрата. Некоторые точки попадут внутрь круга, а некоторые - за его пределы. Чтобы оценить число pi, мы посчитаем общее количество точек и общее количество точек внутри круга. На диаграмме на рисунке 1 описаны квадрат, случайно сгенерированные точки и вписанный круг.

Рисунок 1 – Диаграмма

52

Как мы знаем, площадь круга равна числу пи, умноженному на квадрат радиуса, а площадь квадрата, вписывающего круг, равна четырем, умноженным на квадрат радиуса. Если мы разделим площадь круга на площадь квадрата, вписывающего круг, то получим число пи, разделенное на четыре. Это соотношение также применимо к количеству точек внутри квадрата и количеству точек внутри замкнутого круга.

Итак, давайте посмотрим формулу для оценки pi с использованием метода Монте-Карло:

Далее мы реализуем формулу с помощью Java.

Давайте посмотрим на простую Java-программу для вычисления числа pi с использованием алгоритма Монте-Карло:

import java.util.Random;

public class Main {

void givenPiCalculator() { int totalPoints = 10000; int insideCircle = 0;

Random random = new Random();

for (long i = 0; i < totalPoints; i++) { double x = random.nextDouble() * 2 - 1; double y = random.nextDouble() * 2 - 1; if (x * x + y * y <= 1) {

insideCircle++;

}

}

double pi = 4.0 * insideCircle / totalPoints; assertEquals(Math.PI, pi, 0.01);

}

}

В приведенном выше примере мы генерируем 10000 случайных точек внутри квадрата со стороной длиной два с центром в начале координат. Затем мы проверяем отдельную точку, чтобы увидеть, попадает ли она в окружность. Любая точка на расстоянии единицы от начала координат считается находящейся внутри окружности.

Наконец, мы оцениваем значение числа pi, находя отношение точек внутри круга к общему количеству точек и умножая результат на четыре.

Задание 1:

53

На основе примера, представленного выше, напишем свою реализацию для задания один, второго этапа.

Листинг представлен ниже. В нем происходит генерация случайных величин на основе заданного диапазона 0-8.01(что является крайними точками прямоугольника, в которой находится треугольник, площадь которого необходимо вычислить) . В массивах x и y задаются координаты вершин треугольника. Первые элементы (с 0 индексом), это то значение, что было случайно сгенерировано. Оно будет участвовать при проверке того, попали мы в нужную область (в треугольник) или нет. Первое условие внутри метода start

– проверяет, что не попали ли мы в прямоугольник, который находится внутри треугольника. Если попали – фиксируем промах и регенерируем координаты. Второе условие описывает вхождение в треугольник.

import java.util.Random;

public class Main {

private static final Random random = new Random(); private static final double[] x = {0, 0, 2, 8}; private static final double[] y = {0, 2, 7, 2};

private static final double s = 16; //Площадь треугольника - площадь прямоугольника

public static void main(String[] args) { System.out.println("S(фактическая) = " + s); long n = 1000000;

for (int i = 1; i <= 10; i++) { System.out.println("Попытка " + i + ":"); start(n);

n *= 2;

}

}

private static void start(long n) { int p = 0;

for (long i = 0; i < n; ++i) { x[0] = random.nextDouble(0, 8); y[0] = random.nextDouble(0, 8);

if (x[0] >= 1 && x[0] <= 5 && y[0] >= 3 && y[0] <= 4) { //Условие вхождения в прямоугольник

continue;

}

double a = (x[1] - x[0]) * (y[2] - y[1]) - (x[2] - x[1]) * (y[1] - y[0]);

double b = (x[2] - x[0]) * (y[3] - y[2]) - (x[3] - x[2]) * (y[2] - y[0]);

double c = (x[3] - x[0]) * (y[1] - y[3]) - (x[1] - x[3]) * (y[3] - y[0]);

if ((a >= 0 && b >= 0 && c >= 0) || (a <= 0 && b <= 0 && c <= 0)) { //Условия вхождения в треугольник

p++;

}

}

double sn = (64.0 * p / n); System.out.println("n = " + n); System.out.println("S(n) = " + sn);

System.out.println("E(n) = " + (Math.abs(sn - s) / s * 100));

}

}

54

Формулы из методических указаний, соответствующие тому, что требовалось вычислить.

S(фактическая) = 1/2ah – S(прямоугольника) n – количество попыток

S(n) – полученая площадь методом Монте-Карло

Результаты вычислений представлены на рисунке 2.

Рисунок 2 – Результаты вычислений

55

Задание 2:

Решение с помощью метода Монте-Карло

На рисунке 3 изображены две окружности с равными радиусами, отдаленные друг от друга на расстояние меньшее чем удвоенный радиус.

Рисунок 3 – Пересечение окружностей

Листинг программы, находящей площадь области пересечения представлен ниже.

import java.util.Random; public class Main {

private static final Random random = new Random();

public static void main(String[] args) { int r = 1;

double s = (Math.PI / 4 - 0.5) * 2; System.out.println("Фактическая: " + s); long n = 1200000;

for (int i = 1; i <= 8; i++) { System.out.println("Попытка " + i + ":"); double sn = start(n, r, 0, 0, 1, 1);

System.out.println("E(n) = " + (Math.abs(sn - s) / s * 100)); n *= 2;

}

}

private static double start(long n, double r, double x1, double y1, double x2, double y2) {

long p = 0;

for (long i = 0; i < n; ++i) {

double randX = random.nextDouble(-1, 2); double randY = random.nextDouble(-1, 2);

56

//Условие вхождения в область пересечения

if (include(r, x1, y1, randX, randY) && include(r, x2, y2, randX,

randY)){

p++;

}

}

double sn = 9.0 * p / n; System.out.println("n = " + n); System.out.println("S(n) = " + sn); return sn;

}

private static boolean include(double r, double x, double y, double randX, double randY) {

return Math.sqrt(Math.pow((randX - x), 2) + Math.pow(randY - y, 2))

<= r;

}

}

Результаты вычислений представлены на рисунке 4.

Рисунок 4 – Результаты вычислений методом Монте-Карло

57

Решение с помощью формул:

public class Main {

//На основе формул из https://abakbot.ru/online-2/73-ploshhad- peresecheniya-okruzhnostej

public static void main(String[] args) { result();

}

private static void result() {

final Circle firstCircle = new Circle(0, 0, 1); final Circle secondCircle = new Circle(1, 1, 1);

double distance = Math.sqrt(Math.pow(firstCircle.r, 2) + Math.pow(secondCircle.r, 2));

double f1 = 2 * Math.acos(((firstCircle.r * firstCircle.r) - (secondCircle.r * secondCircle.r) + (distance * distance)) / (2 * firstCircle.r * distance));

double f2 = 2 * Math.acos(((secondCircle.r * secondCircle.r) - (firstCircle.r * firstCircle.r) + (distance * distance)) / (2 * secondCircle.r * distance));

double s1 = ((firstCircle.r * firstCircle.r) * (f1 - Math.sin(f1))) / 2;

double s2 = ((secondCircle.r * secondCircle.r) * (f2 - Math.sin(f2))) / 2;

System.out.println("Расстояние между центрами: " + distance); System.out.println("S = " + (s1 + s2));

}

private record Circle(double x, double y, double r) {}

}

Результаты вычислений представлены на рисунке 5

Рисунок 5 – Результат вычислений

58

Список использованных источников

1)Основы программирования в MATLAB. Учебно-методическое пособие. Задания 1-9. / Гареева Г.А., Григорьева Д.Р.; Издательство - Издательско-полиграфический центр Набережночелнинского института Казанского (Приволжского) федерального университета 2019 г., 104 стр. // URL: https://pro.guap.ru/inside/student/tasks/c90f99bcb3d9a95bbc8d63db499fe947/download

2)Документация по библиотеке Java – Math - https://code-knowledge.com/java-data-types- java-lang-math/#:~:text=java.lang.Math%20– %C2%A0Numerical%20operations%20in%20Java.,built%20into%20Java%20by%20defau lt

3)Предназначение методов стандартной библиотеки java.lang.Math, языка программирования Java - https://javarush.com/groups/posts/2762-klass-java-math-i-ego- metodih

4)Документация по программному обеспечению Matlab - https://www.mathworks.com/products/matlab.html

5)Предназначение и основные особенности программного обеспечения Matlab - https://en.wikipedia.org/wiki/MATLAB

6)Учебно-методические материалы к заданию этапа №2 / Жаринов О.О.; Издательство -

ГУАП,

2024

г.,

7

стр.

URL:

//

https://pro.guap.ru/inside/student/tasks/2e0bae5c66eae52262abc017bae3f00d/download

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]