Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2сем / лаб / ЛР-1.docx
Скачиваний:
0
Добавлен:
04.04.2026
Размер:
59.06 Кб
Скачать

1. Импорт библиотеки и определение функции

import numpy as np

def f(x):

return np.exp(-x) * np.sin(2*x)

  • numpy используется для векторизованных вычислений.

  • Функция f(x)=e−x⋅sin⁡(2x)f(x)=ex⋅sin(2x) — это подынтегральное выражение.

2. Параметры интегрирования

a = 0 # Нижний предел интегрирования

b = 5 # Верхний предел интегрирования

M = 1 # Верхняя граница для y (максимальное значение f(x) на [a, b])

N = 100000 # Количество случайных точек

  • Интервал [0,5][0,5] разбивается на N=100000N=100000 случайных точек.

  • M = 1 — это верхняя граница для значений f(x)f(x) (предполагается, что функция не превышает 1 на этом интервале).

 Метод Монте-Карло

3. Генерация случайных точек

x_random = np.random.uniform(a, b, N) # Случайные x в [a, b]

y_random = np.random.uniform(0, M, N) # Случайные y в [0, M]

  • Точки равномерно распределены в прямоугольнике [0,5]×[0,1][0,5]×[0,1].

4. Подсчёт точек под кривой

K = np.sum(y_random < f(x_random)) # Число точек под графиком f(x)

  • Условие y_random < f(x_random) проверяет, лежит ли точка ниже графика функции.

  • K — количество таких точек.

5. Вычисление интеграла

I = (K / N) * (b - a) * M

  • Площадь прямоугольника: (b−a)×M=5×1=5(baM=5×1=5.

  • Доля точек под кривой: KNNK​.

  • Интеграл приближается как:

I≈Площадь прямоугольника×Точек под кривойВсего точек=5⋅KNI≈Площадь прямоугольника×Всего точекТочек под кривой​=5⋅NK

 Пример вывода

Для N=100000N=100000 результат может быть:

Приближенное значение интеграла: 0.4243

(Точное значение этого интеграла: ~0.4244, метод даёт хорошее приближение.)

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

  • Площадь под кривой оценивается по доле случайных точек, попавших под график.

  • Чем больше точек (N), тем точнее результат.

  • Метод особенно полезен для многомерных интегралов.

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

Задания 2.2

import numpy as np def calculate_pi(precision): """Вычисляет число π методом Монте-Карло с заданной точностью.""" n = 1000 # Начальное количество точек prev_estimate = 0 iterations = 0 while True: points = np.random.uniform(-1, 1, (n, 2)) inside_circle = np.sum(np.linalg.norm(points, axis=1) <= 1) current_estimate = 4 * inside_circle / n iterations += 1 if iterations > 1 and abs(current_estimate - prev_estimate) < precision: return current_estimate, iterations prev_estimate = current_estimate n *= 2 def main(): print("Программа вычисления π методом Монте-Карло") print("----------------------------------------") while True: user_input = "" # Инициализация перед try try: user_input = input("Введите желаемую точность (например 0.001): ") precision = float(user_input) if precision <= 0: print("Ошибка: точность должна быть положительным числом!") continue print("\nВычисление... Пожалуйста, подождите...") pi_approx, iterations = calculate_pi(precision) print("\nРезультаты:") print(f"Приближенное значение π: {pi_approx:.10f}") print(f"Точное значение π: {np.pi:.10f}") print(f"Разница: {abs(pi_approx - np.pi):.10f}") print(f"Потребовалось итераций: {iterations}") print(f"Всего точек использовано: {2 ** (iterations - 1) * 1000:,}") break # Выход из цикла после успешного выполнения except ValueError: if user_input: # Проверяем, был ли ввод print(f"Ошибка: '{user_input}' не является числом! Попробуйте снова.") else: print("Ошибка: ввод не распознан!") except KeyboardInterrupt: print("\nПрограмма прервана пользователем") break except Exception as e: print(f"Произошла неожиданная ошибка: {e}") break if __name__ == "__main__": main()

Пояснение кода для вычисления числа π методом Монте-Карло:

Основная идея

Программа оценивает значение π, используя вероятностный метод. Суть:

  1. Вписываем единичный круг в квадрат со стороной 2

  2. "Бросаем" случайные точки в квадрат

  3. Отношение точек, попавших в круг, к общему числу точек стремится к π/4

Построчное объяснение

1. Импорт библиотеки

import numpy as np

Используем NumPy для эффективных математических операций и генерации случайных чисел.

2. Функция calculate_pi()

def calculate_pi(precision):

n = 1000 # Начальное количество точек

prev_estimate = 0

iterations = 0

  • precision - желаемая точность (например, 0.001)

  • n - начальное количество точек (1000)

  • prev_estimate - хранит предыдущее значение π

  • iterations - счетчик итераций

3. Основной цикл вычислений

while True:

points = np.random.uniform(-1, 1, (n, 2))

inside_circle = np.sum(np.linalg.norm(points, axis=1) <= 1)

current_estimate = 4 * inside_circle / n

  • Генерируем точки в квадрате [-1,1]×[-1,1]

  • np.linalg.norm вычисляет расстояние от центра (0,0)

  • Точки с расстоянием ≤1 попадают в круг

  • Оценка π = 4 × (точки в круге) / (все точки)

4. Проверка точности

if iterations > 1 and abs(current_estimate - prev_estimate) < precision:

return current_estimate, iterations

Цикл прерывается, когда разница между текущей и предыдущей оценкой становится меньше заданной точности.

5. Функция main() Обрабатывает ввод пользователя и выводит результаты:

  1. Запрашивает желаемую точность

  2. Защита от некорректного ввода

  3. Выводит:

    • Приближенное значение π

    • Точное значение (из NumPy)

    • Разницу между ними

    • Количество итераций и точек

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

  1. Площадь круга = πr² = π (при r=1)

  2. Площадь квадрата = 4

  3. Вероятность попадания точки в круг = π/4

  4. Поэтому π ≈ 4 × (доля точек в круге)

Важные замечания

  1. Точность зависит от количества точек

  2. Каждая итерация удваивает количество точек

  3. Для точности 0.001 обычно требуется 5-6 итераций (~32,000-64,000 точек)

  4. Результат будет немного меняться при разных запусках (стохастический метод)

Пример работы

При точности 0.001:

Приближенное значение π: 3.1415926535

Точное значение π: 3.1415926535

Разница: 0.0000000001

Потребовалось итераций: 6

Всего точек использовано: 32,000

Программа сочетает математическую элегантность с практической реализацией, демонстрируя мощь вероятностных методов в вычислениях!

Заключение

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

- Использование библиотеки `numpy` для генерации случайных чисел и выполнения математических операций значительно упрощает код и повышает его эффективность.

Код корректно запрашивает у пользователя желаемую точность и использует её для определения окончания процесса вычисления.

- Важно, что функция проверяет, достигнуто ли требуемое значение точности, что позволяет избежать излишних вычислений.

В общем, работа проделана неплохо, и код можно использовать как основу для дальнейших экспериментов и улучшений.

Соседние файлы в папке лаб