Министерство образования РФ
Санкт-Петербургский государственный электротехнический
университет «ЛЭТИ»
Кафедра вычислительной техники
ОТЧЕТ ПО ЛАБОРАТОРНОЙ РАБОТЕ № 3
по учебной дисциплине «методы оптимизации»
на тему «Исследование методов ЛИНЕЙНОГО ПОИСКА»
Вариант 1
Выполнил:
Студент (ка)___Никитина Т.И._____
Группа___________2375__________
Руководитель:
Алешкевич Павел Александрович
(должность, Ф.И.О.)
Санкт-Петербург
2004
Оглавление:
Задание…………………………………………………………………………….3
Описание методов оптимизации…………………………………………………3
Листинг программы ……………………………………………………………...4
Спецификация программы……………………………………………………….6
Результаты тестирования и Выводы…………………….……………………….7
Ответы на контрольные вопросы………………………………………………...7
Задание
Целью работы является разработка программы, реализующей процедуру минимизации функции многих переменных в заданном направлении;
Реализовать на языке С++ методы оптимизации. Протестировать программу и сравнить результаты работы заданных методов оптимизации при использовании различных критериев окончания поиска и при задании различных значений погрешности локализации минимума. Сделать выводы.
Описание методов оптимизации.
Метод Свенна. (для поиска в пространстве по направлению)
С помощью метода Свенна получают начальный интервал локализации минимума [a,b] .
Начальный этап. Для запуска метода необходимо:
(1) задать x0 – начальная точка.
(2) выбрать шаг h равным 0.001 или min{η,|(y1-y’)/y’1|}, где η=1,2.
(3) выбрать направление поиска p.
Основной этап
Шаг 1. Установить направление убывания функции. Взять x2=x1+h*p. Если f2>f1, поменять направление движения.
Шаг 2. Вычислять xk+1=xk+hk*p, hk=2hk-1 до тех пор пока не придём в точку xn такую что fn>fn-1.
Шаг 3. Установить начальный интервал локализации минимума a1=xn-2 и b1=xn.
Метод Свенна 4.
Начальный этап. Для запуска метода необходимо:
(1) задать x0 – начальная точка.
(2) выбрать шаг h равным 0.001 или min{η,|(y1-y’)/y’1|}, где η=1,2.
(3) выбрать направление поиска p.
Основной этап
Шаг 1. Установить направление убывания функции. h=h, если y’(x0,p)<0 и h=-h, если y’(x0,p)>0.
Шаг 2.Двигаться в направлении р, вычисляя значение функции в точках xk+1=xk+hk*p, hk=2hk-1. Пока производная не поменяет знак, т.е. Y’m-1*Y’m<0
Шаг 3. Фиксируем начальный интервал: [Xm-1,Xm]
Метод Золотого Сечения 2. (для функции нескольких переменных)
Метод Золотого Сечения является процедурой линейного поиска минимума унимодальной функции f(x) на интервале [a, b], отличающейся тем, что на каждой итерации очередная пробная точка делит интервал локализации в отношении постоянном для всех интервалов τ=L2/L1=L3/L2=...Ln/Ln-1.
Начальный этап
(1) Задать константу , начальный интервал [a1, b1] вычисляется методом Свенна.
(2) Вычислить одну стартовую точку x1 = a1 + 0.618L*p L=|a-b|
(3) Положить k = 1.
Основной этап
Шаг 1. Взять очередную точку x2=a1+b1-x1 симметричную исходной x1 и сократить ТИЛ рассмотрением четырёх ситуаций: если x1<x2 и f(x1)<f(x2) то ak+1=ak, bk+1=x2, x1=x1; если x1<x2 и f(x1)>f(x2) то ak+1= x1, bk+1= bk, x1=x2; если x1>x2 и f(x1)<f(x2) то ak+1=x1, bk+1= bk, x1=x1; если x1>x2 и f(x1)>f(x2) то ak+1=ak, bk+1=x1, x1=x2.
Положить k=k+1.
Шаг 2. Проверить критерий окончания поиска: если |a-b| < фиксируем аппроксимирующий минимум x*=(a+b)/2.
и на Шаг 1.
Метод Дэвидона.
Этот метод является аналогом метода кубической аппроксимации в задачах поиска минимума функции нескольких переменных по заданному направлению. Идея метода заключается в том, чтобы на ТИЛ найти аппроксимирующий минимум строя полином 3-го порядка.
Начальный этап:
-
Взять ε, х 0 – начальную точку поиска, p – направление поиска.
-
Найти начальный шаг α1 = min{ η,|(y1-y’)/y’1|}, где η=1,2. y1=y(x1), y’1 =y’(x1,p)
-
Получить начальный интервал поиска [a,b] методом Свенна 4.
Основной этап:
-
Найти аппроксимирующий минимум, т.е. точку r по формулам:
r = a+αr *p
αr = α a +γ*( α b - αa )
γ=(z-f’a+W)/(f’b-f’a+2*W)
W=√z2-f’a*f’b
z=f’a+f’b+3*(fa-fb)/(b-a)
-
Проверить КОП если Y’r<=ε, то остановиться.X= a+ αr *p Иначе сократить ТИЛ двумя способами:
Y’r<0 -> [r,b]
Y’r>0 -> [a,r]
Установить k=k+1 и вернуться на шаг 1.
Можно модифицировать алгоритм – ввести смещение точек на α0 .
Текст программы:
#include <math.h>
#include <conio.h>
#include <iostream.h>
/**********************************Strukturi*********************************/
struct Dot
{
double x1,x2;
};
struct Vek
{
double x1,x2,len;
};
Dot x;
Vek p;
/******************************Celevaya funkciya*****************************/
double f(double k)
{
return (x.x1+k*p.x1)*(x.x1+k*p.x1)+3*(x.x2+k*p.x2)*(x.x2+k*p.x2)+2*(x.x1+k*p.x1)*(x.x2+k*p.x2);
}
/**********************************Ee proizvodnaya***************************/
double df(double k)
{
return (2*(x.x1+k*p.x1)+2*(x.x2+k*p.x2))*p.x1+(6*(x.x2+k*p.x2)+2*(x.x1+k*p.x1))*p.x2;
}
/*********************************Metod Swenna*******************************/
void swann(double* a,double* b)
{
float h1,x1;
h1=0.01;
x1=h1;
if(f(0)<f(x1))
{
h1=-h1;
x1=h1;
}
do
{
h1=2*h1;
x1=x1+h1;
}
while(f(x1-h1)>f(x1));
*a=x1-1.5*h1;
*b=x1;
}
/***********************Metod Zolotogo Se4eniya 2****************************/
double zs_2(double a,double b)
{
double e,x1,x2;
int k=0;
e=0.001;
x1=a+0.618*fabs(b-a);
do
{
x2=a+b-x1;
if((x1<x2)&&(f(x1)<f(x2)))
b=x2;
if((x1<x2)&&(f(x1)>=f(x2)))
{
a=x1;
x1=x2;
}
if((x1>x2)&&(f(x1)<f(x2)))
a=x2;
if((x1>x2)&&(f(x1)>=f(x2)))
{
b=x1;
x1=x2;
}
k++;
}
while(k<5);
return (a+b)/2;
}
/*******************************Metod Devidona*******************************/
double david()
{
int k=1;
double e=0.000000001,dfun,a,b,n,h,r,z,w,a0;
dfun=df(0);
h=0.000001;
if(dfun>0)
{
p.x1=-p.x1;
p.x2=-p.x2;
dfun=df(0);
}
do
{
h=h+2*h;
}
while(dfun*df(h)<0);
a=h/3;
b=h;
do
{
z=df(a)+df(b)+3*(f(a)-f(b))/(b-a);
w=sqrt(z*z-df(a)*df(b));
r=(w-df(a)+z)/(2*w-df(a)+df(b));
r*=(b-a);
if(df(r)<=e) return r;
if(df(r)>0) b=r;
else a=r;
}
while(k<10);
return r;
}
/********************************Osnovnaya programma*************************/
void main()
{
double a,b,n,kmin;
Dot min;
clrscr();
cout<<"\n-Laboratornaya rabota 3. Issledovanie metodov lineynogo poiska.-";
cout<<"\n-------------------------Variant 1------------------------------";
cout<<"\n----------------------MZS -> Devidona---------------------------";
cout<<"\n-------------- Vipolnila: Nikitina T., gr. 2375 ----------------";
cout<<"\n\n\nCelevaya funkciya: x1^2+3*x2^2+2*x1*x2";
cout<<"\nVvedite koordinati na4al'noy to4ki poiska: "<<'\n';
cin>>x.x1>>x.x2;
cout<<"\nZadayte napravlenie poiska: "<<'\n';
cin>>p.x1>>p.x2;
p.len=sqrt(p.x1*p.x1+p.x2*p.x2);
p.x1=p.x1/p.len;
p.x2=p.x2/p.len;
p.len=1;
swann(&a,&b);
if(a>b)
{
n=a;
a=b;
b=n;
}
kmin=zs_2(a,b);
x.x1=x.x1+kmin*p.x1;
x.x2=x.x2+kmin*p.x2;
kmin=david();
min.x1=x.x1+kmin*p.x1;
min.x2=x.x2+kmin*p.x2;
cout<<"\nNaydenaya to4ka minimuma: ("<<min.x1<<" "<<min.x2<<")"<<'\n';
getch();
}
/*****************************************************************************/
Спецификация программы.
В программе приведены два метода поиска – это линейный метод поиска, модифицированный для функций нескольких переменных, метод Золотого сечения 2. Также приведен метод Дэвидона – кубической аппроксимации для функций нескольких переменных.
x - точка
p – направление поиска
k – колличество шагов
e - точность
a – левая граница отрезка
b – правая граница отрезка
len - норма
Результаты тестирования различных методов
Ниже приведены таблицы с результатами работы программы для двух функций, с различными стартовыми точками и точностями вычисления.
Точность: |
|
0.0001 |
|
0.00001 |
|
0.000001 |
X0=(1,1) |
К |
X* |
K |
X* |
K |
X* |
Метод Золотого сечения 2 |
22 |
(0.255816; -0.116276) |
33 |
(-0.255813; -0.11628) |
31 |
(0.255814; -0.116279) |
Метод Дэвидона |
1 |
(0.255814; -0.116279) |
1 |
(0.255814; -0.116279) |
1 |
(0.255814; -0.116279) |