Выбор и обоснование используемых методов решения.
1. Для решения задачи одномерной оптимизации будет использован метод золотого сечения: Этот метод эффективен с точки зрения количества вычислений функций на отдельной итерации, хотя проигрывает методу дихотомии по количеству требуемых итераций для достижения заданной точности. 2. Для проведения численного интегрирования выберем метод Симпсона:
Так как в состав наших подынтегральных функции входит нелинейные, поэтому большей точностью будет обладать метод Симпсона.
3. Для решения нелинейного уравнения выберем метод половинного деления:
Метод половинного деления сходится для любых непрерывных функций f(x) в том числе недифференцируемых. Последнее является преимуществом, т.к. вычисление производной сложной функции достаточно проблематично.
Описание методов решения.
Метод золотого сечения.
В основу метода положено разбиение отрезка неопределенности [a;b] в соотношении золотого сечения, такого, что отношение длины его большей части ко всей длине отрезка равно отношению длины его меньшей части к длине его большей части:
l
l2 l1
где k1, k2 - коэффициенты золотого сечения.
В методе золотого сечения каждая точка (х1 и х2)осуществляет золотое сечение отрезка.
или
Точка х1 осуществляет золотое сечение не только отрезка [a;b], но и отрезка [a;х2]. Точно так же точка х2 осуществляет золотое сечение не только отрезка [a;b], но и отрезка [х1;b]. Это приводит к тому, что значение целевой функции на каждой итерации (кроме первой) вычисляется один раз.
Сокращение отрезка неопределенности следующим образом:
1) если f(x1) f(x2), то x*[a0;x2]
2) если f(x1) > f(x2), то x*[x1;b0]
После каждой итерации длина отрезка неопределенности сокращается в 1.618 раза. Длина конечного отрезка неопределенности n = 0.618n0, где 0= (b-a) – начальная длина отрезка.
Условие окончания
процесса итераций n
.
Отсюда можно найти количество итераций,
необходимое для достижения точки
минимума:
отсюда
или
Формула Симпсона.
Для получения формулы Симпсона применяется квадратичный интерполирующий полином. За элементарный интервал интегрирования принимается отрезок [xi;xi+2]. Поэтому интервал интегрирования [a;b] разбивается на n отрезков, где n=2m – четное число (рис.2).
Для
всего интервала интегрирования [a;b]
формула Симпсона выглядит следующим
образом:
Тестирование процедур.
Для проверки правильности
процедуры, реализующей метод золотого
сечения, в качестве теста используем
функцию
,
имеющую на отрезке [0;6] единственный
минимум Xmin=
4 , а значение функции в этой точке
f(Xmin)=16.
Проведем проверку правильности тестовых данных с использованием средств пакета MathCad:
Код программы:
Option Strict On
Option Explicit On
Imports System.Math
Public Class Form6
'процедура ввода
Sub vvod(ByVal t As TextBox, ByRef x As Double)
x = Val(t.Text)
End Sub
'процедура вывода
Sub vivod(ByVal x As Double, ByVal T As TextBox)
T.Text = CStr(x)
End Sub
'целевая функция
Function f(ByVal x As Double) As Double
Return -((x - 4) ^ 2) + 16
End Function
'метод золотого сечения на отрезке [o1,o2]
'а2-оптимальное значение параметра
Sub gold(ByVal o1 As Double, ByVal o2 As Double, ByVal Eee As Double, _
ByRef a2 As Double, ByRef k As Double, ByRef z As String)
Dim k1, k2, x1, x2, f1, f2 As Double
k1 = (3 - Sqrt(5)) / 2
k2 = 1 - k1
x1 = o1 + k1 * (o2 - o1)
x2 = o1 + k2 * (o2 - o1)
f2 = f(x1)
z = ""
Do Until (o2 - o1) < Eee
If (-f1) < (-f2) Then
o2 = x2 : x2 = x1
x1 = o1 + k1 * (o2 - o1)
f2 = f1
f1 = f(x1)
Else
o1 = x1 : x1 = x2 : f1 = f2
x2 = o1 + k2 * (o2 - o1)
f2 = f(x2)
End If
z = z + Format(o1, "0.00000") + Space(3) + Format(o2, "0.00000") + Space(3) + Format(x1, "0.00000") + Space(3)
z = z + Format(x2, "0.00000") + Space(5) + Format(f1, "0.00000") + Space(5) + Format(f2, "0.00000") + Space(4) + Format(o2 - o1, "0.00000") + vbNewLine
Loop
a2 = (o1 + o2) / 2
k = f(a2)
End Sub
Private Sub Button12_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button12.Click
Dim z As String = ""
vvod(TextBox13, Eee)
vvod(TextBox14, o1)
vvod(TextBox15, o2)
gold(o1, o2, Eee, a2, k, z)
TextBox16.Text = z
vivod(a2, TextBox17)
vivod(k, TextBox18)
End Sub
Private Sub Button13_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button13.Click
Form5.Show()
Me.Hide()
End Sub
Private Sub Button14_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button14.Click
Form7.Show()
End Sub
End Class
Результат выполнения:
Результаты, полученные при тестировании, совпадают с истинными. Программа работает верно.
Метод Симпсона.
Для
проверки правильности процедуры,
реализующей метод Симпсона, в качестве
теста используем интеграл
Схема алгоритмов:
Код программы:
Option Strict On
Option Explicit On
Imports System.Math
Public Class Form7
'процедура ввода
Sub vvod(ByVal t As TextBox, ByRef x As Double)
x = Val(t.Text)
End Sub
'процедура вывода
Sub vivod(ByVal x As Double, ByVal T As TextBox)
T.Text = CStr(x)
End Sub
'целевая функция
Function f(ByVal x As Double) As Double
Return -((x - 4) ^ 2) + 16
End Function
Sub reshenie1i(ByVal a As Double, ByVal b As Double, ByVal Eee As Double, ByRef I1 As Double)
Dim n, i, ccc As Integer
Dim h, s1, x As Double
n = 2
h = (b - a) / n
I1 = (f(a) + 4 * f((a + b) / 2) + f(b)) * h / 3
Do
n = n * 2
h = (b - a) / n
s1 = I1
ccc = 4
x = a
I1 = f(a) + f(b)
For i = 1 To n - 1
x = x + h
I1 = I1 + ccc * f(x)
ccc = 6 - ccc
Next
I1 = I1 * h / 3
Loop Until Abs(I1 - s1) / 15 < Eee
End Sub
Private Sub Button15_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button15.Click
Dim a, b, Eee, I1 As Double
vvod(TextBox19, Eee)
vvod(TextBox20, a)
vvod(TextBox21, b)
reshenie1i(a, b, Eee, I1)
vivod(I1, TextBox22)
End Sub
Private Sub Button16_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button16.Click
Form6.Show()
Me.Hide()
End Sub
Private Sub Button17_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button17.Click
Form8.Show()
End Sub
End Class
Результат выполнения:
Результаты, полученные при тестировании, совпадают с истинными. Программа работает верно.
Метод половинного деления.
Для проверки правильности процедуры, решим уравнение –(x-4)^2+16 = 0
Схема алгоритмов:
Код программы:
Option Strict On
Option Explicit On
Imports System.Math
Public Class Form8
'процедура ввода
Sub vvod(ByVal t As TextBox, ByRef x As Double)
x = Val(t.Text)
End Sub
'процедура вывода
Sub vivod(ByVal x As Double, ByVal T As TextBox)
T.Text = CStr(x)
End Sub
'целевая функция
Function f(ByVal x As Double) As Double
Return -((x - 4) ^ 2) + 16
End Function
'решение уравнения
Sub reshenieUr(ByVal с As Double, ByVal ee As Double, ByVal Eee As Double, ByRef Xx As Double)
Dim Cc, EEEe, f1, f2, f3 As Double
Dim n As Integer
Cc = c
EEEe = ee
n = 0
Do
n = n + 1
Xx = (Cc + EEEe) / 2
f1 = f(Cc)
f2 = f(Xx)
f3 = f(EEEe)
If (f2 * f3 < 0) Then
Cc = Xx
Else
EEEe = Xx
End If
Loop Until Abs(EEEe - Cc) < Eee
End Sub
Private Sub Button18_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button18.Click
Dim c, ee, Xx, Eee As Double
vvod(TextBox24, Eee)
vvod(TextBox26, c)
vvod(TextBox23, ee)
reshenieUr(c, ee, Eee, Xx)
vivod(Xx, TextBox25)
End Sub
Private Sub Button19_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button19.Click
Form7.Show()
Me.Hide()
End Sub
Private Sub Button20_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button20.Click
End
End Sub
End Class
Результат выполнения:
Результаты, полученные при тестировании, совпадают с истинными. Программа работает верно.
