Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа №3.doc
Скачиваний:
14
Добавлен:
01.05.2014
Размер:
106.5 Кб
Скачать

Метод Дэвидона.

Этот метод является аналогом метода кубической аппроксимации в задачах поиска минимума функции нескольких переменных по заданному направлению. Идея метода заключается в том, чтобы на ТИЛ найти аппроксимирующий минимум строя полином 3-го порядка.

Начальный этап:

  1. Взять ε, х 0 – начальную точку поиска, p – направление поиска.

  2. Найти начальный шаг α1 = min{ η,|(y1-y’)/y’1|}, где η=1,2. y1=y(x1), y’1 =y’(x1,p)

  3. Получить начальный интервал поиска [a,b] методом Свенна 4.

Основной этап:

  1. Найти аппроксимирующий минимум, т.е. точку r по формулам:

r = a+αr *p

αr = α a +γ*( α b - αa )

γ=(z-f’a+W)/(fb-f’a+2*W)

W=√z2-f’a*f’b

z=f’a+f’b+3*(fa-fb)/(b-a)

  1. Проверить КОП если Y’r<=ε, то остановиться.X= a+ αr *p Иначе сократить ТИЛ двумя способами:

Y’r<0 -> [r,b]

Y’r>0 -> [a,r]

Установить k=k+1 и вернуться на шаг 1.

Можно модифицировать алгоритм – ввести смещение точек на α0 .

Спецификация программы.

В программе приведены два метода поиска – это линейный метод поиска, модифицированный для функций нескольких переменных, метод Золотого сечения 2. Также приведен метод Дэвидона – кубической аппроксимации для функций нескольких переменных. В программе присутствуют два вспомогательных алгоритма поиска начального интервала: метод Свенна1 и Свенна4. Присутствуют функции вычисления градиента и функция вычисления производной по направлению в точке. В качестве переменных-векторов используются обьекты класса complex, представляющие собой обьект из двух полей double, т.е. двумерные векторы. Также используются некоторые методы этого класса.

Текст программы.

#include<iostream.h>

#include<math.h>

#include<conio.h>

#include<complex.h>

//++++++++++++++++++++++++++++++++++++++++++++++

complex a,b;

int k=1,k1=1,k2=1,k3=1;

//++++++++++++++++++++++++++++++++++++++++++++++

double f (complex x)

{

return (real(x)*real(x)+3*imag(x)*imag(x)+2*real(x)*imag(x));

}

//++++++++++++++++++++++++++++++++++++++++++++++

complex grad (complex x)

{

return (complex(2*real(x)+2*imag(x),2*real(x)+6*imag(x)));

}

//++++++++++++++++++++++++++++++++++++++++++++++

double dy (complex x,complex p)

{

return (real(grad(x))*real(p)+imag(grad(x))*imag(p));

}

//++++++++++++++++++++++++++++++++++++++++++++++

void Svenn(complex x0,complex p)

{

double h=0.001;

if (f(x0)<f(x0+h*p)) h=-h;

x0=x0+h*p;

while (f(x0)<f(x0-h*p))

{

h=2*h;

x0=x0+h*p;

k++;

}

if (h>0)

{

a=x0-h*p-p*h/2;

b=x0;

}

else

{

a=x0;

b=x0-h*p-p*h/2;

}

}

//++++++++++++++++++++++++++++++++++++++++++++++

complex ZS2(complex x1)

{

double R=0.5*sqrt(5)-0.5,e=0.0001;

complex x0;

x0=complex(real(a)+R*(real(b)-real(a)),imag(a)+R*(imag(b)-imag(a)));

while (abs(b-a)>=e)

{

if ((abs(x0-a)<abs(x1-a))&&(f(x0)<f(x1)))

{

b=x1;

x0=complex(real(a)+R*(real(b)-real(a)),imag(a)+R*(imag(b)-imag(a)));

x1=a+b-x0;

}

else

if ((abs(x0-a)<abs(x1-a))&&(f(x0)>f(x1)))

{

a=x0;

x1=complex(real(a)+R*(real(b)-real(a)),imag(a)+R*(imag(b)-imag(a)));

x0=a+b-x1;

}

else

if ((abs(x0-a)>abs(x1-a))&&(f(x0)<f(x1)))

{

a=x1;

x0=complex(real(a)+R*(real(b)-real(a)),imag(a)+R*(imag(b)-imag(a)));

x1=a+b-x1;

}

else

if ((abs(x0-a)>abs(x1-a))&&(f(x0)>f(x1)))

{

b=x0;

x1=complex(real(a)+R*(real(b)-real(a)),imag(a)+R*(imag(b)-imag(a)));

x0=a+b-x1;

}

k1++;

};

return ((a+b)/2);

}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void Svenn4(complex x0,complex p)

{

double h=0.001;

if (dy(x0,p)>0) h=-h;

x0=x0+h*p;

while (dy(x0,p)*dy(x0-h*p,p)>=0)

{

h=2*h;

x0=x0+h*p;

k2++;

}

a=x0-h*p;

b=x0;

}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

complex Davidon(complex x0,complex p)

{

double da=real(a-x0)/real(p),db=real(b-x0)/real(p),z,w,r,e=0.0001;

if (da>db)

{

r=db;

db=da;

da=r;

}

a=x0+da*p;

b=x0+db*p;

z=dy(a,p)+dy(b,p)+3*(f(a)-f(b))/(db-da);

w=sqrt(z*z-dy(a,p)*dy(b,p));

r=da+(db-da)*(z-dy(a,p)+w)/(dy(b,p)-dy(a,p)+2*w);

while (dy(x0+r*p,p)>=e)

{

if (dy(x0+r*p,p)<0)

da=r;

else

db=r;

a=x0+da*p;

b=x0+db*p;

z=dy(a,p)+dy(b,p)+3*(f(a)-f(b))/(db-da);

w=sqrt(z*z-dy(a,p)+dy(b,p) );

r=da+(db-da)*(z-dy(a,p)+w)/(dy(b,p)-dy(a,p)+2*w);

k3++;

}

return (x0+r*p);

}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void main ()

{

clrscr();

complex x0 = complex(1,1),p = complex(2,3),x;

Svenn(x0,p);

cout <<" Swenn: [ "<< a <<" ; "<<b<<" ] "<<" k= " << k << endl;

x=a+b-x0;

x=ZS2(x);

cout <<" ZS2: X= "<< x <<" k= " << k1 << endl;

Svenn4(x0,p);

cout <<" Swenn4: [ "<< a <<" ; "<<b<<" ] "<<" k= " << k2 << endl;

x=Davidon(x0,p);

cout <<" Davidon: X= "<< x <<" k= " << k3 << endl;

getch();

}