1) Задать x0 – произвольная начальная точка.
2) выбрать шаг h равным 0.01…0.001(если x0 = 0) или 0.01*|x0|(если x0 не = 0).
3) e1=e2 (0.01…0.001)
Основной этап:
Шаг 1:
Получить 3 равностоящих точки методом Свенна2:
-
Установить направление убывания целевой функции. Для этого надо
взять x2=x1+h. Если f1<f2, то надо поменять направление движения
(h=- h и взять x2=x1+h).
-
xk+1=xk+2* hk-1 пока не будет xm-1: fm-1< fm .
-
xm+1=(xm+xm-1)/2.
-
Из f(xm+1)и f(xm-1) взять минимальную
-
Переименовать а= xm-2 b= xm-1 с= xm+1 или а= xm-1 b= xm+1 с= xm
Шаг 2:
Найти d=b+1/2*((b-a)*(f(a)-f(c))/(f(a)-2*f(b)+f(c)));
Шаг 3:
КОП: Если l(d-b)/bl<=e1 и l(f(d)-f(b))/f(b)l<=e2 выполняются, то x*=(b-d)/2
Иначе: x0 = min(f(b),f(d)) и h1=h/2 goto Шаг1.
Спецификация программы.
В программе реализован метод прямого поиска начального интервала локализации. Далее в программе производится сравнение двух методов простого линейного поиска и интерполяционного метода. Сравниваются методы Фибоначчи 1 и метод Дэвиса-Свенна-Кемпи..
Текст программы:
#include <iostream.h>
#include <conio.h>
#include <math.h>
//+++++++++++++++++++++++++++++++++++++++++++++
int k,k1;
//+++++++++++++++++++++++++++++++++++++++++++++
double f (double x)
{
return (2*pow(x,2)-pow(2.718281828,x));
}
//+++++++++++++++++++++++++++++++++++++++++++++
long Fib (long x)
{
long s, tmp;
if(x>=1)
{
s=1;
tmp=0;
for(long k=0; k<x; k++)
{
s=s+tmp;
tmp = s-tmp;
}
return s;
}
else
return 1;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++
void Svenn(double *a, double *b, double x, double h)
{
k=1;
if(f(x)<f(x+h))
h=-h;
while(f(x)<f(x-h))
{
h=2*h;
x=x+h;
k++;
}
*b=x-h-h/2;
*a=x;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++
double F1(double a, double b, double e)
{
k=1;
double Ln=0.01*e,l,m;
long n=0;
while(Fib(n)<(b-a)/Ln)
n++;
l=a+(Fib(n-2)*(b-a))/(Fib(n));
m=a+(Fib(n-1)*(b-a))/(Fib(n));
while(k<n-1)
{
if(f(l)<f(m))
{
b=m;
m=l;
l=a+(Fib(n-k-2)*(b-a))/Fib(n-k);
}
else
{
a=l;
l=m;
m=a+(Fib(n-k-1)*(b-a))/Fib(n-k);
}
k++;
}
if(f(l)<=f(m))
return (a+m)/2;
else
return (l+b)/2;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
double DSK(double *a,double *b, double *c,double x0, double h)
{
k=1;
k1=1;
double x1,d,x,e=0.01;
do
{
x1=x0+h;
if(f(x0)<f(x1))
{
h=-h;
x1=x0+h;
}
do
{
h=2*h;
x1=x1+h;
k++;
}
while(f(x1-h)>f(x1));
x=(x1+(x1-h))/2;
if(f(x)<f(x1-h))
{
*a=x1-h;
*b=x;
*c=x1;
}
else
{
*a=x1-1.5*h;
*b=x1-h;
*c=x;
}
if(*a>*c)
{
x=*a;
*a=*c;
*c=x;
}
d=(*b)+1/2*(((*b)-(*a))*(f(*a)-f(*c)))/(f(*a)-2*f(*b)+f(*c));
if(fabs((d-(*b))/(*b))<=e && fabs((f(d)-f(*b))/f(*b))<=e)
return ((*b)+d)/2;
else
{
if(f(*b)<f(d))
x0=(*b);
else
x0=d;
}
h=h/2;
k1++;
}
while(1);
}
//++++++++++++++++++++++++++++++++++++++++++++
void main()
{
clrscr();
double h=0.01,a,b,c,x0=1,e=0.001;
cout<<"e="<<e<<" x0="<<x0<<endl;
cout<<endl;
cout<<"--- Svenn ---"<<endl;
Svenn(&a,&b,x0,h);
cout<<"a="<<a;
cout<<" b="<<b;
cout<<" k="<<k<<endl;
cout<<endl;
cout<<"--- Fibonachchi-1 ---"<<endl;
double x=x0;
x=F1(a,b,e);
cout<<"x="<<x;//<<endl;
cout<<" k="<<k<<endl;
cout<<endl;
cout<<"--- Svenn2 ---"<<endl;
DSK(&a,&b,&c,x0,h);
cout<<"a=" <<a;
cout<<" b="<<b;
cout<<" c="<<c;
cout<<" k="<<k<<endl;
cout<<endl;
cout<<"--- DSK ---"<<endl;
cout<<"x="<<x;
cout<<" k="<<k1;
getch();
}
Результаты тестирования различных методов:
Ниже приведены таблицы с результатами работы программы для двух методов, с различными стартовыми точками и точностями вычисления.
|
Точность: |
|
0.01 |
|
0.001 |
0.0001 |
|
X0=1 |
К |
X* |
K |
X* |
X* |
|
Метод Свенна |
10 |
[-0.022 ; 0.746] |
10 |
[-0.022 ; 0.746] |
[-0.022 ; 0.746] |
|
Метод Фибоначчи |
19 |
0.357334 |
24 |
0.357401 |
0.357403 |
|
Метод Свенна2 |
10 |
-0.023 0.233 0.489 |
10 |
-0.023 0.233 0.489 |
-0.023 0.233 0.489 |
|
Метод ДСК |
1 |
0.357334 |
1 |
0.357401 |
0.357403 |
Выводы
В данной работе были использованы методы: Свенна - получения начального интервала локализации минимума (для метода Фибоначчи 1), Свенна2 – получения трех равностоящих точек (для метода ДСК), Фибоначчи1 - линейного поиска минимума унимодальной функции f(x) на замкнутом интервале [a, b], ДСК - интерполяционный метод нахождения минимума функции в 3 этапа: 1) Свенн2; 2) d; 3) возврат с h1=h/2 . Сравнивая методы стоит отметить, что при выборе начальной точки близкой к истинному значению минимума интерполяционный метод работает практически в три раза быстрее прямого метода при заданной точности. Однако, если взять начальную точку далеко от истинного минимума, то метод ДСК намного уступает прямому методу. Отсюда следует сделать вывод о том, что в начале поиска стоит использовать линейные методы поиска начального интервала, если интервал невелик и можно с некоторой точностью установить значение начальной точки поиска, то следует использовать интерполяционный метод, если же интервал велик и выбрать близкое значение начальной точки сложно, то стоит использовать линейный метод поиска минимума.
Ответы на контрольные вопросы:
-
Когда целесообразно использовать методы полиномиальной интерполяции?
Методы полиномиальной интерполяции нужно использовать в случае, если начальная точка поиска близка к истинному минимуму.
-
Сравните организацию поиска в методах ДСК и Пауэлла.
В методе Пауэлла после вычисления апрксимационного минимума и выбора лучшей точки из b или d, мы берем 2 соседние слева и справа точки и называем левую a, правую – c. В методе ДСК после выбора лучшей точки мы сторим 2 новые симметричные относительно центральной точки a и c.
-
Как строится система из 4-х уравнений в методе кубической интерполяции?
Уравнение аппроксимации целевой функции y(x)=Ax3+Bx2+Cx+D имеет 4 неизвестных. На отрезке [a,b] накладываем ограничения:
F(a)=y(a) -> находим D
F(b)=y(b) = Ab3+Bb2+Cb+D
F’(a) = y’(a) находим С
F’(b) = y’(b) = 3Ab2+2Bb+c
-
Достоинства и недостатки методов интерполяции в задачах оптимизации.
Данные методы решают задачу локализации минимума за очень малое число итераций при условии близости начальной точки поиска к истинному минимуму. Если это условие не выполняется, то интерполяционный метод работает намного медленнее и менее эффективно прямых методов поиска минимума.
-
Почему при минимизации целевых функций используют комбинированные стратегии поиска? Это делается для того чтобы убрать недостатки интерполяционных методов на начальных этапах, когда минимум можно определить с большой погрешностью и эти методы неэффективны. И сделать поиск минимума более эффективным на последующих этапах.
-
Выполните одну итерацию метода ДСК при поиске минимума f(x) = x2 - x, x = 3.
Предположим, что сработал метод Свенна2 и за 12 итераций мы узнали 3 точки a= -0.039 b=0.473 c=0.986 . Ищем апроксимационный минимум d = 0.3585 Далее мы берем лучшую точку из b и d. В данном случае это b. И строим 2 симметричные относительно нее точки a=b-h и c=b+h Уменьшаем h=h/2. Проверяем КОП и возвращаемся на шаг 1.
