Вычисление площади фигуры, ограниченной двумя кривыми с помощью Python
 4 июня 2016 г.
 4 июня 2016 г. Archy
 Archy Просмотров: 25266
 Просмотров: 25266 RSS
 RSS алгоритм вычисление площади фигуры python, вычисление площади python, вычисление площади фигуры python
 алгоритм вычисление площади фигуры python, вычисление площади python, вычисление площади фигуры pythonСледующий пример, который мы рассмотрим - задача о вычислении площади фигуры, ограниченной двумя кривыми. Здесь, в этом примере, мы используем вложенные операторы цикла(то есть один оператор цикла вызывается в теле другого оператора цикла).
Что касается непосредственно решаемой задачи, то нам предстоит вычислить площадь фигуры, которая ограничена двумя кривыми, уравнения которых y(x) = x и y(x) = x^2. Графики этих кривых представлены на рис. 1.
Это прямая линия и парабола. Кривые пересекаются в двух точках: в точке x = 0, y = 0 и в точке x = 1, y = 1(точки определяются как решение уравнения x = x^2). Получается такой своеобразный "лепесток", площадь которого нам и предстоит вычислить.
Наша задача имеет точное решение. А именно, площадь S указанной фигуры следующая:
Однако мы будем использовать несколько иной подход.
Рис. 1. Вычисление области фигуры, ограниченной двумя кривыми
Метод, который описывается далее и применяется нами для вычисления площади фигуры, имеет отношение к теории вероятностей и математической статистике(обычно такой подход называют методами Монте-Карло).
При вычислении площади фигуры мы будем исходить из следующих соображений. Во-первых, замечаем, что область ограниченная кривыми, полностью попадает в единичный квадрат с левой нижней вершиной в точке начала координат и правой верхней вершиной в точке с единичными координатами. Если мы случайным образом выберем точку внутри этого квадрата, то она с некоторой вероятностью попадает в область, что ограничена кривыми (то есть попадает внутрь "лепестка").
Теория вероятностей утверждает, что эта самая вероятность равна отношению площадей "лепестка" и квадрата. У квадрата с единичной стороной площадь равна единице. Поэтому площадь "лепестка"(которую нам необходимо вычислить) равняется вероятности, с которой случайным образом выбранная точка попадает внутрь "лепестка". Это будет "во вторых".
В третьих, если взять очень много случайных точек, равномерно распределенных по квадрату, и вычислить отношение количества точек внутри "лепестка" к общему количеству точек, в идеале получим оценку, близкую к вероятности попадания случайно выбранной точки внутрь "лепестка".
Мы всю эту процедуру немного модифицируем и поступим следующим образом. Вместо того чтобы генерировать случайны точки, покроем весь квадрат равноотстоящими узловыми точками. Посчитаем, сколько их попало внутрь "лепестка"(то есть области, ограниченной кривыми), и поделим на общее количество точек. Это и будет результат.
Программный код, в котором реализован такой подход, представлен ниже:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Количество равных интервалов, на которые
# делятся стороны единичного квадрата
n = 500
# "Цена деления" - расстояние между соседними точками
dz = 1 / n;
# Количество точек, которые попадают внутрь области
pts = 0
# Начальное значение индекса, определяющего столбец точек
i = 0
# Внешний оператор цикла. Перебираем столбцы точек
while i <= n:
    # x - координата точки
    x = dz * i
    # Начальное значение второго индекса для точек столбца
    j = 0
    # Внутренний оператор цикла. Перебираем точки
    # в одном столбце
    while j <= n:
        # y - координата точки
        y = dz * j
        # Условный оператор: проверяем, попала ли точка
        # внутрь области
        if y <= x and y >= x**2:
            # Еще одна точка внутри области
                pts += 1
        # Значение второго индекса увеличиваем на единицу
        j += 1
    # Значение первого индекса увеличиваем на единицу
    i += 1
# Вычисляем площадь фигуры
S = pts / (n + 1) ** 2
# Отображаем результат
print("Площадь фигуры: " + str(S))
Результат, который приведен ниже, достаточно близок к точному решению:
Чтобы понять логику вычислений, имеет смысл мысленно представить, как мы разбиваем каждую из сторон квадрата на определенное количество интервалов. Количество этих интервалов записывается в переменную n(то есть значение 500).
Границу интервалов будем называть узловыми точками. Через каждую узловую точку на сторонах квадрата проводим горизонтальные и вертикальные линии. Точки пересечений этих линий - это именно те точки, которые нам нужны. Каждую такую точку можно "идентифицировать" с помощью двух индексов.
Первый индекс определяет узловую точку по горизонтали, а второй - узловую точку по вертикали. На пересечении линий, проходящих через эти узловых точки, находится "идентифицируемая" точка внутри квадрата.
Если мы зафиксируем первый индекс, и будем брать разные значения для второго индекса, то все соответствующие точки будут находится на одной вертикальной прямой. Про такие точки будем говорить, что они находятся в одном столбце. Если зафиксировать второй индекс и брать разные значения первого индекса, то все соответствующие точки будут находиться на одной горизонтальной прямой. Про такие точки можем говорить, что они формируют ряд точек.
В каждому ряду и в каждом столбце размещено ровно n + 1 точек ( если учитывать и те точки, что находятся на координатных осях).
Расстояние (по горизонтали или по вертикали) между двумя соседними узловыми точками равняется, очевидно, единице, деленной на количество интервалов, на которые разбивалась каждая из сторон квадрата: такая "цена деления" записывается в переменную dz(значение 1/n). В переменную pts(начальное значение 0) будем записывать количество точек, которые попали внутрь "лепестка".
В условном операторе проверяется условие y <= x and y >= x**2. Это и есть условие попадания точки с координатами X(переменная x) и Y(переменная y) внутрь области, ограниченной кривыми y = x и y = x ^ 2. Чтобы точка попадала в это область, необходимо чтобы одновременно выполнялись два условия. Во-первых, точка должна находиться ниже прямой y = x, а это имеет место, если y <= x (нестрогое неравенство - если мы допускаем, чтобы точка могла оказаться не только ниже прямой, но и непосредственно на прямой.)
Во-вторых, точка должна находиться выше параболы y = x ^ 2 (или на самой параболе - такой вариант мы тоже допускаем). Соответствующее условие выглядит как y >= x ^ 2. Следовательно, должно выполняться соотношение x ^ 2 <= y <= x. Если перевести это на язык Python, то получим y <= x and y >= x**2. Кстати, вместо инструкции y <= x and y >= x**2 вполне законно можно было использовать выражение x ** 2 <= y <= x. Такого типа выражения в Python допустимы.
Начальное значение индекса i , определяющего столбец точек, должно быть нулевым (нулевой индекс соответствует точке на координатной оси). Через первый индекс, напомним, "нумеруются" столбцы точек. Когда запускается внешний оператор цикла, в нем проверяется условие i <=n. Поэтому цикл выполняется до тех пор, пока значение индексной переменной i не превысит значение переменной n.
В теле оператора цикла командой x = dz * i вычисляется координата х (вдоль горизонтальной оси - абсцисса) для точек, находящихся в данном столбце (столбец, напомним, определяется значением индекса i ). Также поскольку далее мы планируем перебирать точки в столбце, командой j = О устанавливаем начальное ну левое значение для второго индекса, (определяющего положение внутренних точек). После этого выполняется второй, внутренний оператор цикла. В нем проверяется условие j <= n - то есть второй индекс j будет увеличиваться (об этом мы узнаем позже) до тех пор, пока он не превысит граничное значение n.
В теле внутреннего оператора цикла командой y = dz * j вычисляется координата у для точки в столбце (координата вдоль вертикальной оси-ордината). С помощью условного оператора проверяем, попадает ли точка внутрь "лепестка", и если так, то командой pts += 1 на единицу увеличиваем значение переменной рts (в которую, напомним, записывается количество точек, попадающих внутрь "лепестка").
Перед завершением внутреннего оператора цикла командой j = j + 1 второй индекс увеличивается на единицу. Это последняя команда внутреннего оператора цикла. Внутренний оператор цикла является предпоследней "командой" внешнего оператора цикла. А последняя команда внешнего оператора цикла - это инструкция i += 1 , которой на единицу увеличивается значение первого индекса.
После выполнения внешнего оператора цикла, переменная pts содержит значение количества точек, которые попадают внутрь "лепестка". Общее количество точек, как несложно догадаться, равняется (n + 1) ** 2 (в каждом из n + 1 столбцов по n + 1 точек - всегда (n + 1)^2 точек). Поэтому если мы поделим одно значение на другое, получим площадь "лепестка". Соответствующее значение вычисляется командой S = рts / (n + 1) ** 2. Наконец, командой print отображаем результат.




