Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Метод Дэвидсона / Zs2-devidona
.cppСпецификация программы.
В программе приведены два метода поиска – это линейный метод поиска,
модифицированный для функций нескольких переменных,
метод Золотого сечения 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();
}
Соседние файлы в папке Метод Дэвидсона