- •Министерство образования рф
- •Отчет по лабораторной работе № 6
- •Оглавление:
- •Задание:
- •Описание методов оптимизации:
- •Спецификация программы: Текст программы:
- •Результаты тестирования программы
- •Каким образом можно проверить положительную определенность гессиана?
- •В чем достоинства метода Ньютона по сравнению с уже известными Вам методами?
- •Есть ли у метода Ньютона какие-либо недостатки, и если да, то как их можно устранить?
- •Какова геометрическая интерпретация метода Ньютона и его модификаций?
Министерство образования рф
Санкт-Петербургский государственный электротехнический
университет «ЛЭТИ»
Кафедра САПР
Отчет по лабораторной работе № 6
по учебной дисциплине «методы оптимизации»
на тему «Исследование модификаций ньютоновских оптимизационных процессов»
Вариант 1
Выполнили:
Смирнов С.А.
Маркосов А.С.
Баранов А.А.
Группа: 5372
Факультет: КТИ
Проверил:
(должность, Ф.И.О.)
Санкт-Петербург
2007
Оглавление:
Задание…………………………………………………………………………….3
Описание методов оптимизации…………………………………………………3
Спецификация программы……………………………………………………….4
Листинг программы ……………………………………………………………...5
Результаты тестирования и Выводы…………………….……………………….7
Ответы на контрольные вопросы………………………………………………...8
Задание:
Цель работы – изучение метода Ньютона и его модификаций, а также разработка программы, удовлетворяющей требованиям лабораторной работы 5.
Методы оптимизации:
М1 – обобщенный метод Ньютона;
Функция y(x) |
Начальная точка (x1)t |
Значение минимума (x*)t |
100(x2 – x12)2 + (1 – x1)2 |
(–1.2; 1) (1.5; 2) (–2; –2) |
(1; 1) |
(x1 – 1)2 + (x2 – 3)2 + 4(x3 + 5)2 |
(4; –1; 2) |
(1; 3; –5) |
Описание методов оптимизации:
Метод Ньютона:
Модификации метода ньютона направлены на:
- снижение чувствительности к выбору начальной точки;
- уменьшение затрат на вычисление обратной матрицы;
- сохранение положительной определенности гессиана во всех точках вычисления;
- уменьшение объема вычислений при расчете вторых производных, т.е. минимизировать затраты на решение СЛАУ;
- обеспечение релаксационного процесса при котором .
Обобщенный метод Ньютона:
Начальный этап:
Задать произвольную начальную точку x0Rn ;
Задать точность вычислений Eps1=Eps2=0.0000001-0.0001;
Задать кол-во шагов M=100 (например);
Положить счетчик итераций К=1;
Основной этап:
Шаг 1. Установить направление поиска минимума. Для этого взять pk=-(Hk)-1gk.
Шаг 2. Минимизировать целевую функцию по Alpha вдоль полученного pk.
Шаг 3. Перейти в новую точку Xk+1=Xk+alphakpk.
Шаг 4. Проверить КОП (например, К≥М или (норма градиента)≤eps)
Спецификация программы: Текст программы:
laba6F.h
class Function
{
public:
Matrix GetHk(Matrix X, Function F);
Matrix Newton(Matrix x1, Function F);
inline double Val (Matrix X) { double x1 = X.element[0][0], x2 = X.element[1][0]; return (x1+1)*(x1+1)+(x2-1)*(x2-1); }
inline double df_dx1 (Matrix X) { double x1 = X.element[0][0], x2 = X.element[1][0]; return 2*x1+2; }
inline double df_dx2 (Matrix X) { double x1 = X.element[0][0], x2 = X.element[1][0]; return 2*x2-2; }
inline double df_dx1dx1 (Matrix X) { return 2; }
inline double df_dx1dx2 (Matrix X) { return 0; }
inline double df_dx2dx1 (Matrix X) { return 0; }
inline double df_dx2dx2 (Matrix X) { return 2; }
inline double df_dp (Matrix X, Matrix P)
{
Matrix g = this->AntiGrad(X);
return g.element[0][0]*P.element[0][0] + g.element[1][0]*P.element[1][0];
}
inline Matrix AntiGrad (Matrix X)
{
Matrix g (2, 1);
g.element[0][0] = -this->df_dx1(X);
g.element[1][0] = -this->df_dx2(X);
return g;
}
double GetAlpha (Matrix X, Matrix P)
{
double Alpha=0, h=0.00001, a, b, c, d, dc, dd;
Matrix X1 = X;
if (this->Val(X) < this->Val(X+P*h))
h *= -1;
while(this->Val(X + P*h) > this->Val(X + P*(2*h)))
{
h *= 2;
}
if (h/2 > h*2)
{
a = h*2;
b = h/2;
}
else
{
a = h/2;
b = h*2;
}
while ((b-a) > 0.0001)
{
dc = this->Val(X + P*(a+(b-a)/4));
dd = this->Val(X + P*(b-(b-a)/4));
if (dc > dd)
{
a = a + (b-a)/4;
}
else
{
b = b - (b-a)/4;
}
}
Alpha = (b+a) / 2;
return Alpha;
}
};
laba6M.h
#include <iostream.h>
#include <conio.h>
#include <math.h>
class Matrix
{
public:
int w, h;
double element [3][3];
Matrix (void) {w = 0; h = 0;}
Matrix (int y, int x)
{
w = x; h = y;
for (int i = 0; i < y; i++)
for (int j = 0; j < x; j++)
element[i][j] = 0;
}
double Determenant (void)
{
if (h != w) return 0;
if (h == 1) return element[0][0];
if (h == 2) return element[0][0]*element[1][1] - element[0][1]*element[1][0];
if (h == 3) return element[0][0]*element[1][1]*element[2][2] - element[0][0]*element[1][2]*element[2][1] - element[0][1]*element[1][0]*element[2][2] -
element[0][2]*element[1][1]*element[2][0] + element[1][0]*element[2][1]*element[0][2] + element[0][1]*element[1][2]*element[2][0];
return 0;
}
void PrintMatrix (void)
{
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
cout<<element[i][j];
cout<<endl;
}
}
Matrix Inverse (void)
{
double d = 1 / this->Determenant ();
if (h != w) return *this;
Matrix m (h, w);
if (h == 1) element[0][0] = 1 / element[0][0];
if (h == 2)
{
m.element[0][0] = this->element[1][1]*d;
m.element[0][1] = - this->element[0][1]*d;
m.element[1][0] = - this->element[1][0]*d;
m.element[1][1] = this->element[0][0]*d;
}
return m;
}
Matrix operator * (Matrix X)
{
Matrix res (2, 1);
res.element[0][0] = element[0][0]*X.element[0][0] + element[0][1]*X.element[1][0];
res.element[1][0] = element[1][0]*X.element[0][0] + element[1][1]*X.element[1][0];
return res;
}
Matrix operator * (double a)
{
Matrix res (h, w);
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++)
res.element[i][j] = element[i][j] * a;
return res;
}
Matrix operator + (Matrix X)
{
Matrix res (h, w);
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++)
res.element[i][j] = element[i][j] + X.element[i][j];
return res;
}
// for vectors only
double Module (void)
{
double res = 0;
for (int i = 0; i < h; i++)
res += element[i][0] * element[i][0];
return sqrt (res);
}
};
laba6.cpp
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include "laba6M.h"
#include "laba6F.h"
//поиск нового значения Hk
Matrix Function :: GetHk(Matrix X, Function F)
{
Matrix H(2, 2);
H.element[0][0] = F.df_dx1dx1 (X);
H.element[0][1] = F.df_dx1dx2 (X);
H.element[1][0] = F.df_dx2dx1 (X);
H.element[1][1] = F.df_dx2dx2 (X);
return H;
}
//метод Ньютона
Matrix Function :: Newton (Matrix x1, Function F)
{
Matrix H (2, 2);
Matrix P (2, 1);
Matrix X = x1;
Matrix tmp (2, 1);
int s = 0;
do
{
if (!(s++%10))
{
H = GetHk (X, F);
tmp = F.AntiGrad(X);
P = H * F.AntiGrad (X);
s = 1;
}
X = X + P * F.GetAlpha(X, P);
tmp = F.AntiGrad (X);
}
while (tmp.Module() > 0.0001); //критерии окончания поиска
return (X); //искомый минимум
}
void main()
{
//начальные параметры
Matrix startPoint(2,1); //задание стартовых значений
Matrix result(1,2); //для хранения результата
startPoint.element[0][0] = -1;
startPoint.element[1][0] = -1;
//заданная функция
Function func;
//вызов метода Ньютона
result=func.Newton(startPoint,func);
cout<<"Minimum:"<<endl;
result.PrintMatrix();
getch();
}