Численные методы. Учебное пособие для СПО
.pdf
legend('метод Эйлера','точное решение') function y = eulerFunc
prev = y0;
for i = 1:length(xlist)
y = prev + h * func(xlist(i), prev); prev = y;
eulerlist(i) = prev; end
end
function y = exactFunc for i = 1:length(xlist)
exactList(i) = exp(sin(xlist(i))); end
end end
function res = func(x,y) res = y * cos(x);
end
6.1.2. Улучшенный метод Эйлера
Модифицированный метод Эйлера (метод Хойна) позволяет уменьшить погрешность на каждом шаге при помощи коррекции шага Эйлера с использованием среднего значения производных по формуле:
1 = ( , )
{ 2 = ( + , + 1)
+1 = + 2 (1 + 2)
Реализация на языке Python
61
def heun_method(f, t0, y0, h, n_steps): t = [t0]
y = [y0]
for _ in range(n_steps): k1 = f(t[-1], y[-1])
k2 = f(t[-1] + h, y[-1] + h * k1) y_next = y[-1] + h * 0.5 * (k1 + k2) t_next = t[-1] + h
y.append(y_next) t.append(t_next)
return t, y
Реализация на языке Matlab
function A = MetodEilera(y0,h,Xstart,Xend) tic
f = @(x,y) x.^2 + y; y = y0;
x = Xstart;
C = 0;
Xmas = zeros(ceil(abs(Xend-Xstart/h)),1); Ymas = zeros(ceil(abs(Xend-Xstart/h)),1); while x < Xend-h
C = C + 1;
y1 = y + h * f(x,y);
y = y + h * (f(x,y)+f(x+h,y1))/2; x = x+h;
Xmas(C) = x; Ymas(C) = y; disp([x,y1,y]); end plot(Xmas,Ymas); A = "END";
toc end
6.1.3. Метод Рунге-Кутта
62
Модифицированная формулировка имеет вид:
|
= ( |
, ) |
|
|
|||
1 |
|
|
|
|
|
|
|
= ( + |
|
, + |
|
) |
|||
2 |
2 |
||||||
2 |
|
|
|
1 |
|||
= ( + |
|
, + |
|
) |
|||
2 |
2 |
||||||
3 |
|
|
|
2 |
|||
4 = ( + , + 3)
{ +1 = + 6 ( 1 + 2 2 + 2 3 + 4)
Метод Рунге-Кутта заключается в использовании четырех промежуточных вычислений для повышения точности.
Реализация на языке Python
def rk4_method(f, t0, y0, h, n_steps): t = [t0]
y = [y0]
for _ in range(n_steps): k1 = f(t[-1], y[-1])
k2 = f(t[-1] + h/2, y[-1] + h/2 * k1) k3 = f(t[-1] + h/2, y[-1] + h/2 * k2) k4 = f(t[-1] + h, y[-1] + h * k3)
y_next = y[-1] + h/6 * (k1 + 2*k2 + 2*k3 + k4) t_next = t[-1] + h
y.append(y_next) t.append(t_next)
return t, y
6.1.4. Метод Адамса
63
Метод Адамса — многошаговый метод, использующий предыдущие вычисленные точки для прогнозирования следующего значения.
Требует начального использования других методов (например, метод Рунге-Кутта). Методы Адамсы делят на два типа: явные (используют предыдущие значения для экстраполяции) и неявные (используют будущие значения при решении нелинейных уравнений). Примером явного метода является метод АдамсаБэшфорта, общая форма, которого описывается так:
−1+1 = + ∑ (−, −),
=0
где — шаг, — коэффициенты метода, — количество шагов. Количество шагов, также определяет порядок метода.
Примером неявного метода является метод АдамсаМоултона. Общая форма, которая учитывает (+1, +1):
−2+1 = + ∑ (−, −)
=−1
Явный метод более быстрый, но менее устойчивый. Неявный более точный, но требуется итераций. Также популярным является комбинированный метод Предиктор-корректор, объ-
единяющий оба этих метода.
В библиотеках Python есть готовое решение, которое можно применять для вычислений (например, solve_ivp).
64
6.2. Разностные методы решения краевой задачи
Краевая задача (КЗ) для ОДУ отличается от задачи Коши тем, что условия заданы не в одной точке, а на границах интервала. Например:
{ |
′′ + ( ) ′ + ( ) = ( ), |
[ ; ] |
|
( ) = , |
( ) = |
|
|
|
|
||
Разностный метод (метод сеток) — это численный под-
ход, основанный на замене производных разностными аналогами и решении полученной системы алгебраических уравнений.
Основные этапы метода можно разбить на несколько шагов. Первое, что необходимо сделать — это построить сетки.
|
Интервал [ ; ] |
разбивается |
|
на |
|
частей с шагом |
|||
= |
− |
. Получаем |
точки сетки |
|
|
= + , |
= 1,2, … , . |
||
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
Искомые значения будут иметь вид: ≈ ( ). |
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
Вторым шагом будет аппроксимация производных: |
||||||||
|
Первая производная: y′( ) ≈ |
+1− −1 |
|
|
|
||||
|
|
|
|
|
|
||||
|
|
|
|
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
||
|
Вторая производная: y′′( ) ≈ |
|
+1−2 + −1 |
|
|
||||
|
|
|
2 |
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
Затем, третьим шагом, переходим к построению разностной схемы. Подставляем аппроксимации в исходное ОДУ. Для урав-
нения ′′ + ( ) ′ + ( ) = ( ) в точке получим: |
|||||||||
|
|
|
|
|
|
|
|
|
|
|
− 2 + |
|
− |
|
|
|
|||
|
+1 |
|
−1 |
+ ( ) |
+1 |
−1 |
+ ( ) |
= ( ) |
|
|
|
|
|
|
|
||||
|
|
2 |
|
|
|
2 |
|
|
|
|
|
|
|
|
|
|
|
||
65
Упростив выражение, получим уравнение, которое сформирует систему линейных уравнений для :
(1 − 2 ) −1 + (−2 + 2 ) + (1 + 2 ) +1 = 2 .
При решении задач необходимо учесть краевые условия: чаще используемые граничные условия Дирихле (значения функций на краях) и условия Неймана (значения производной) аппроксимируются дополнительно.
Полученная система имеет трехдиагональную матрицу и решается методами, описанными выше.
Реализация на языке Python
import numpy as np
import matplotlib.pyplot as plt
def solve_bvp(p, q, f, a, b, alpha, beta, N): h = (b - a) / N
x = np.linspace(a, b, N + 1)
# Инициализация матрицы и правой части
A = np.zeros((N - 1, N - 1)) F = np.zeros(N - 1)
for i in range(N - 1): xi = x[i + 1]
A[i, i] = -2 + h**2 * q(xi) if i > 0:
A[i, i - 1] = 1 - h/2 * p(xi) if i < N - 2:
A[i, i + 1] = 1 + h/2 * p(xi)
66
F[i] = h**2 * f(xi)
# Учет краевых условий
F[0] -= (1 - h/2 * p(x[1])) * alpha F[-1] -= (1 + h/2 * p(x[-2])) * beta
# Решение системы
y_inner = np.linalg.solve(A, F)
y = np.concatenate(([alpha], y_inner, [beta]))
return x, y
# Пример: y'' - y = x, y(0) = 0, y(1) = 1 p = lambda x: 0
q = lambda x: -1 f = lambda x: x a, b = 0, 1
alpha, beta = 0, 1 N = 100
x, y = solve_bvp(p, q, f, a, b, alpha, beta, N)
# Точное решение для проверки def exact_solution(x):
return (np.exp(1) / (np.exp(2) - 1)) * (np.exp(x) - np.exp(-x)) - x
plt.plot(x, y, 'b-', label='Численное решение')
plt.plot(x, exact_solution(x), 'r--', label='Точное решение') plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.show()
67
Самостоятельная работа
Теоретические вопросы:
1.Что такое обыкновенное дифференциальное уравнение?
2.В чем различия между задачей Коши и краевой зада-
чей?
3.В каких случаях эффективен метод Эйлера?
4.Какие модификации возможны для улучшения метода
Эйлера?
5.Какова сущность метода Рунге-Кутта?
6.Когда целесообразно использовать многошаговые методы вроде метода Адамса?
7.Как устроены разностные методы решения краевых за-
дач?
8.Существуют ли гарантии абсолютной устойчивости численных методов?
9.Какие особенности присущи решению жестких дифференциальных уравнений?
10.Всегда ли удается найти численное решение любой задачи Коши?
Практические задания:
1. Реализуйте метод Эйлера для уравнения ′ = +
сусловием (0) = 1.
2.Примените улучшенный метод Эйлера для решения уравнения ′ = sin( ) , (0) = 0.
3.Решите уравнение ′ = −∆ методом Рунге-Кутта четвертого порядка (∆= 1, (0) = 1).
4.Примените метод Адамса второго порядка для урав-
нения ′ = 2 − , (0) = 0.
5.Сравните эффективность методов Эйлера и РунгеКутта на одном и том же уравнении.
6.Разработайте программу для исследования влияния шага интегрирования на точность решения.
68
7. Реализуйте краевую задачу методом конечных разно-
стей.
8.Оцените надежность полученных решений при изменении параметров краевой задачи.
9.Предложите альтернативный подход для жесткого дифференциального уравнения.
10.Примените методы численного решения ОДУ для моделирования динамики механической системы.
69
7. ЗАДАЧИ ЛИНЕЙНОГО ПРОГРАММИРОВАНИЯ
Линейное программирование — это математический ме-
тод оптимизации, в котором целевая функция и ограничения являются линейными, а переменные принимают неотрицательные значения.
Целевая функция: = 1 1 + 2 2 + + →
/.
Переменные: 1, 2, … , ≥ 0. Ограничения:
11 1 + 12 2 + + 1 ≥ 1
{ 11 1 + 22 2 + + 2 ≥ 2
1, 2, … , ≥ 0.
Есть несколько типов задач, отличающихся по целевой функции. Стандартная задача: целевая функция максимизация, а ограничения неравенства типа (≤). Каноническая задача: целевая функция максимизация или минимизация, ограничения типа (=). Общая задача: комбинация равенств и неравенств. Рассмотрим популярные алгоритмы.
Симплекс-метод применяется для решения общих задач ЛП. Идея, которого состоит в переходе от одной вершины многогранника допустимых решений к другой с увеличением значения целевой функции. Шаги алгоритма:
1.Приведение к канонической форме.
2.Построение начального базисного решения.
3.Итеративное улучшение решения через симплекстаблицы.
4.Проверка на оптимальность.
70
