gadget59.ru · практика Численные методы · Практическая работа №2 · 15 слайдов
01

Практическая работа №2

Решение алгебраических и трансцендентных уравнений численными методами

ОП.10 Численные методы · Специальность 09.02.07 «Информационные системы и программирование»
Объём: 2 академических часа

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

🎯 Корни уравнений ✂️ Метод бисекции 🔄 Метод итераций 📊 matplotlib 🐍 Python
02

Зачем мы это делаем? (Введение)

В школе вы решали уравнения вида x² - 5x + 6 = 0 через дискриминант. Но в реальной IT-разработке 90% уравнений выглядят страшно: e^x - 3x = 0 или cos(x) - x = 0. Для них не существует готовых формул.

Где это применяется?

Главная цель практики: не просто «нажать кнопки», а понять, как компьютер ищет ответ там, где человек бессилен. Мы разобьём задачу на два этапа: сначала найдём, где примерно лежит корень, а потом уточним его до 6 знаков после запятой.

03

Этап 1: Графический метод (Зачем нужен график?)

Прежде чем писать код, который будет «угадывать» число, нужно понять, где вообще искать. Графический метод — это самый наглядный способ.

Как это работает?

Мы строим график функции y = f(x). Корень уравнения f(x) = 0 — это точка, где график пересекает горизонтальную ось Ox (ось абсцисс).

Библиотека matplotlib: в Python за графики отвечает библиотека matplotlib (от слов matlab и plotting). Она умеет рисовать линии, точки, сетки и подписи. Мы будем использовать её модуль pyplot.

Что мы ищем на графике?

Нам нужно найти небольшой отрезок [a, b], на котором график пересекает ось ровно один раз. Именно этот отрезок мы потом отдадим компьютеру для точных вычислений.

04

Этап 2: Аналитический метод (Теорема Больцано — Коши)

График — это хорошо, но компьютеру нужны числа. Здесь на помощь приходит фундаментальная теорема математического анализа.

Теорема Больцано — Коши (о промежуточном значении): если функция f(x) непрерывна на отрезке [a, b] и на концах отрезка принимает значения разных знаков (то есть одна положительная, а другая отрицательная), то внутри этого отрезка обязательно есть хотя бы один корень.

f(a) · f(b) < 0

Это условие означает, что функция «перепрыгнула» через ноль. Чтобы найти такой отрезок автоматически, мы используем метод перебора с шагом: берём точку x, считаем f(x), делаем маленький шаг вперёд, снова считаем. Если знак изменился — корень пойман!

05

Этап 3: Метод половинного деления (Бисекция)

Теперь, когда у нас есть отрезок [a, b], где спрятан корень, мы начинаем его «сжимать». Метод бисекции (от лат. bisectio — рассечение надвое) — самый надёжный алгоритм в численных методах.

Геометрический смысл

Представьте, что вы ищете нужный дом на длинной улице. Вы делите улицу пополам и смотрите, в какой половине нужный дом. Потом делите эту половину пополам. И так далее, пока не упрётесь в нужную дверь.

Алгоритм

  1. Находим середину отрезка: c = (a + b) / 2.
  2. Считаем f(c).
  3. Если f(a) и f(c) разных знаков — корень в левой половине. Делаем b = c.
  4. Иначе — корень в правой половине. Делаем a = c.
  5. Повторяем, пока длина отрезка |b - a| не станет меньше заданной точности ε (эпсилон).

Плюс метода: он всегда сходится, если корень есть. Минус: сходится медленно (нужно много шагов).

06

Этап 4: Метод простой итерации

Этот метод быстрее, но требует хитрости. Нам нужно переписать уравнение f(x) = 0 в виде x = φ(x) (читается «фи от икс»).

Как переписать?

Пример: x³ - x - 1 = 0. Переносим x вправо: x³ = x + 1. Извлекаем кубический корень: x = ∛(x + 1). Теперь φ(x) = ∛(x + 1).

Как считать?

Берём любое начальное число x₀ (например, 1.0). Подставляем его в φ(x) и получаем x₁. Подставляем x₁ и получаем x₂. И так далее, пока числа не перестанут меняться.

xₙ₊₁ = φ(xₙ)

Условие сходимости: метод сработает, только если производная |φ'(x)| < 1 на нашем отрезке. Проще говоря, функция φ(x) должна быть «пологой». Если вы переписали уравнение неудачно, метод «разбежится» в бесконечность.

07

Варианты заданий

Преподаватель выдаёт вам один из четырёх вариантов. Для каждого варианта уже подготовлено удачное преобразование для метода итераций, чтобы вы не тратили время на алгебру.

Вариант Уравнение f(x) = 0 Тип Отрезок [a, b] Функция φ(x) для итераций
1 x³ − x − 1 = 0 Алгебраическое [1, 2] x = ∛(x + 1)
2 cos(x) − x = 0 Трансцендентное [0, 1] x = cos(x)
3 e^x − 3x = 0 Трансцендентное [0, 1] x = e^x / 3
4 x³ − 2x − 5 = 0 Алгебраическое [2, 3] x = ∛(2x + 5)

Точность для всех вариантов: ε = 10⁻⁶ (в коде записывается как 1e-6). Это означает, что мы хотим, чтобы ошибка была меньше одной миллионной.

08

Задание №1. Графическая локализация

Постройте график функции f(x) на заданном отрезке и визуально убедитесь, что корень там есть.

Разбор кода

Мы используем библиотеку numpy (для быстрых математических операций с массивами) и matplotlib.pyplot (для рисования).

import numpy as np
import matplotlib.pyplot as plt

# 1. Описываем нашу функцию
def f(x):
    return x**3 - x - 1  # ЗАМЕНИТЕ НА СВОЙ ВАРИАНТ!

# 2. Создаём массив из 400 точек от 0 до 3
x = np.linspace(0, 3, 400)
y = f(x)

# 3. Рисуем график
plt.figure(figsize=(10, 6))
plt.plot(x, y, label='f(x)', color='blue', linewidth=2)
plt.axhline(0, color='black', linewidth=1)  # Горизонтальная ось Ox
plt.axvline(0, color='black', linewidth=1)  # Вертикальная ось Oy
plt.grid(True, alpha=0.3)  # Сетка для удобства
plt.legend()
plt.title('График функции f(x)')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.show()

Что сделать: скопируйте код, замените формулу на свой вариант, запустите. Сделайте скриншот появившегося окна и вставьте в отчёт с подписью: «Рисунок 1. График функции для варианта N».

09

Задание №2. Аналитическое отделение корней

Теперь заставим компьютер найти отрезок [a, b] автоматически, используя теорему Больцано — Коши.

import math

def f(x):
    return x**3 - x - 1  # ВАШ ВАРИАНТ

# Метод перебора с шагом 0.1
a = 0
h = 0.1
x = a

print("Таблица значений f(x):")
print(f"{'x':<10} {'f(x)':<15}")
print("-" * 25)

while x <= 3:
    fx = f(x)
    print(f"{x:<10.1f} {fx:<15.6f}")
    
    # Проверяем смену знака с предыдущей точкой
    if x > a and f(x - h) * fx < 0:
        print(f"\n✅ Корень найден на отрезке [{x - h}, {x}]")
        break
    
    x += h

Как это работает: цикл while идёт по оси x с шагом h = 0.1. Мы умножаем значение функции в текущей точке на значение в предыдущей. Если произведение отрицательное (< 0), значит, знаки разные, и корень зажат между ними.

10

Задание №3. Метод половинного деления

Реализуем алгоритм бисекции. Обратите внимание: мы используем abs(b - a) > epsilon вместо сравнения с нулём, чтобы избежать проблем с плавающей точкой (вспомните Лекцию 1 про 0.1 + 0.2).

def f(x):
    return x**3 - x - 1  # ВАШ ВАРИАНТ

def bisection(a, b, epsilon):
    step = 0
    print(f"{'Шаг':<5} {'a':<12} {'b':<12} {'c':<12} {'f(c)':<15}")
    print("-" * 60)
    
    # Цикл работает, пока отрезок больше требуемой точности
    while abs(b - a) > epsilon:
        c = (a + b) / 2
        fc = f(c)
        step += 1
        print(f"{step:<5} {a:<12.8f} {b:<12.8f} {c:<12.8f} {fc:<15.2e}")
        
        if fc == 0:
            return c  # Идеальный случай (редко бывает с float)
        elif f(a) * fc < 0:
            b = c  # Корень в левой половине
        else:
            a = c  # Корень в правой половине
    
    return (a + b) / 2

# Запуск
a, b = 1, 2  # Отрезок из Задания 2
epsilon = 1e-6
root = bisection(a, b, epsilon)
print(f"\n🎯 Корень найден: x ≈ {root:.8f}")
print(f"Проверка: f(x) = {f(root):.2e}")
11

Задание №4. Метод простой итерации

Теперь используем функцию φ(x) из таблицы на Слайде 7. Не забудьте импортировать math для функций cos и exp.

import math

def phi(x):
    # ВАШ ВАРИАНТ из таблицы! Например, для варианта 1:
    return (x + 1) ** (1/3)  

def simple_iteration(x0, epsilon, max_iter=100):
    x = x0
    print(f"{'Итерация':<10} {'x':<15} {'|x_new - x|':<15}")
    print("-" * 40)
    
    for n in range(max_iter):
        x_new = phi(x)
        diff = abs(x_new - x)
        print(f"{n+1:<10} {x_new:<15.8f} {diff:<15.2e}")
        
        # Условие остановки: изменение стало меньше точности
        if diff < epsilon:
            return x_new
        x = x_new
    
    print("⚠️ Метод не сошёлся!")
    return None

# Запуск
x0 = 1.0  # Начальное приближение (берём середину отрезка [a, b])
epsilon = 1e-6
root = simple_iteration(x0, epsilon)
print(f"\n🎯 Корень найден: x ≈ {root:.8f}")

Параметр max_iter=100: это «аварийный тормоз». Если вы ошиблись в формуле φ(x) и метод разбегается, цикл остановится через 100 шагов, а не зависнет навсегда.

12

Задание №5. Сравнение методов

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

Как измерить время в Python?

import time

start = time.time()  # Засекаем время ДО
# ... ваш код ...
end = time.time()    # Засекаем время ПОСЛЕ

print(f"Время выполнения: {(end - start) * 1000:.2f} миллисекунд")

Таблица для отчёта

Заполните эту таблицу в своём отчёте на основе выводов консоли:

Параметр Метод бисекции Метод итераций
Найденный корень
Число шагов/итераций
Значение f(x) в корне
Время работы (мс)

Вывод: напишите 2-3 предложения. Какой метод потребовал меньше шагов? Почему, как вы думаете, бисекция надёжнее, но медленнее?

13

Инструкция по оформлению отчёта

Отчёт — это лицо инженера. Следуйте этому чек-листу, чтобы работа была принята с первого раза:

  1. Титульный лист: ФИО, группа, номер и название практической работы.
  2. Цель работы: скопируйте из Слайда 2.
  3. Задание 1 (График): скриншот окна matplotlib с подписью «Рисунок 1».
  4. Задание 2 (Перебор): скриншот консоли с таблицей и найденным отрезком.
  5. Задание 3 (Бисекция): скриншот консоли с таблицей итераций и итоговым корнем.
  6. Задание 4 (Итерации): скриншот консоли с таблицей итераций и итоговым корнем.
  7. Задание 5 (Сравнение): заполненная таблица и текстовый вывод.
  8. Приложение: полный исходный код всех программ (можно скопировать текстом в конец документа).

Формат файла: PDF или DOCX. Имя файла: Фамилия_Практика2_ЧисленныеМетоды.pdf.

14

Типичные ошибки и как их избежать

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

Золотое правило программиста: любой итерационный цикл должен иметь «аварийный выход» по числу шагов. Это спасёт вас от зависания программы во время сдачи работы преподавателю.

15

Работа завершена!

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

Теперь вы понимаете, как работают инженерные калькуляторы, физические движки игр и финансовые алгоритмы. Сохраните отчёт и подготовьте его к сдаче.

🎯 Корни ✂️ Бисекция 🔄 Итерации 🐍 Python 📊 matplotlib

Отличная работа! Вы сделали большой шаг в мире численных методов.