Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа №7 / LABA7
.CPP#include <conio.h>
#include <iostream.h>
#include <math.h>
// Подключаем класс для работы с матрицами
#include "matrix.cpp"
TMatrix<double> Po,Xo;
double f(TMatrix<double> &x,int fun)
{
switch(fun)
{
case 1:
return 2*x[1]*x[1]+2*x[1]*x[2]+2*x[2]*x[2]-x[1]+1;
break;
case 2:
return pow(x[1]-1,2)+pow(x[2]-3,2)+4*pow(x[3]+5,2);
break;
default:cout<<"Such variant of a choice is not possible!"<<endl;
break;
}
}
// Численное вычисление производной любой функции в точке "х" по направлению "р"
double df(TMatrix<double> &x,TMatrix<double> &p, int fun)
{
double eps=0.0001;
return (f(x+p*eps,fun)-f(x,fun))/(eps);
}
// Возвращает направление поиска, параллельное оси координат
TMatrix<double> Ord(int size, int i) // size - число переменных функции
// i - число обращений к этой функции
{
TMatrix<double> res(size,1);
for(int k=1; k <= size; k++)
{
if (k!=i)
{
res[k]=0;
}
else
{
res[k]=1;
}
}
return res;
}
// Возвращает вектор градиента функции в точке "х"
TMatrix<double> Grad(TMatrix<double> &x,int fun)
{
int i=x.getSizeRow();
TMatrix<double> res(i,1);
for (int k = 1;k<=i;k++)
{
res[k]=df(x,Ord(i,k),fun);
}
return res;
}
// Вычисление шага
double Alpfa(double X1, int fun)
{
double X2, a, b, c, d, h, Min;
int i=0;
double e,e2=0.0000001;
e=e2;
h = 0.001*X1;
if (!h)
h = 0.001;
X2 = X1 + h;
if (f(Xo+X1*Po,fun) < f(Xo+X2*Po,fun))
h = -h;
do
{
X2 = X1 + h;
while(f(Xo+X1*Po,fun) > f(Xo+X2*Po,fun))
{
h = 2*h;
X1 = X2;
X2 = X1 + h;
}
if (f(Xo+X1*Po,fun) < f(Xo+((X1+X2)/2)*Po,fun))
{
b = X1;
c = (X1+X2)/2;
a = 2*b - c;
}
else
{
a = X1;
b = (X1+X2)/2;
c = 2*b - a;
}
d = b + (b-a)*(f(Xo+a*Po,fun)-f(Xo+c*Po,fun))/(f(Xo+a*Po,fun) - 2*f(Xo+b*Po,fun) + f(Xo+c*Po,fun))/2;
h = h/2;
if (f(Xo+b*Po,fun) < f(Xo+d*Po,fun))
{
X1 = b;
}
else
{
X1 = d;
}
i++;
}
while((fabs((d - b)/b) > e) || (fabs((f(Xo+d*Po,fun) - f(Xo+b*Po,fun))/f(Xo+b*Po,fun)) > e2));
Min = (b+d)/2;
cout<<"Dsk iteracii: "<<i<<"\n";
return Min;
}
// Критерий окончания поиска
double norma(TMatrix<double> &x)
{
double res=0;
int m=x.getSizeRow(), n=x.getSizeCol();
for(int i=1; i<=m; i++)
{
for(int j=1; j<=n; j++)
{
res+=fabs(x(i,j)*x(i,j));
}
}
return sqrt(res);
}
// Метод Даниела
TMatrix<double> Daniel(TMatrix<double> x,double eps,int &max_step,int fun)
{
// Переменные
double epsilon=eps;
TMatrix<double> p1, p2, g1, g2, x1, x2, x3, gamma, r1, r2,y;
int k=1;
double alfa1, alfa2, beta1;
// Установка размера матриц и векторов
p1.setSize(x.getSizeRow(),x.getSizeCol());
p2.setSize(x.getSizeRow(),x.getSizeCol());
g1.setSize(x.getSizeRow(),x.getSizeCol());
g2.setSize(x.getSizeRow(),x.getSizeCol());
x1.setSize(x.getSizeRow(),x.getSizeCol());
x2.setSize(x.getSizeRow(),x.getSizeCol());
x3.setSize(x.getSizeRow(),x.getSizeCol());
r1.setSize(0,0);
r2.setSize(0,0);
Po.setSize(x.getSizeRow(),x.getSizeCol());
x1=x;
do
{
cout<<"Iteraciya "<<k<<endl;
cout<<"x1="<<endl;
x1.writeArray();
p1=Grad(x1,fun)*-1;
cout<<"p1="<<endl;
p1.writeArray();
Po=p1;
Xo=x1;
alfa1=Alpfa(0,fun);
x2=x1+p1*alfa1;
cout<<"x2="<<endl;
x2.writeArray();
y.setSize(x.getSizeRow(),x.getSizeCol());
y=Grad(x2,fun);
if (norma(y)<epsilon)
{
return x2;
}
g1=Grad(x1,fun);
cout<<"g1="<<endl;
g1.writeArray();
g2=Grad(x2,fun);
cout<<"g2="<<endl;
g2.writeArray();
gamma.setSize(x.getSizeRow(),x.getSizeCol());
gamma=g2-g1;
cout<<"gamma="<<endl;
gamma.writeArray();
r1=g2.getTranspose()*gamma;
r2=p1.getTranspose()*gamma;
beta1=(r1[1]/r2[1]);
cout<<"beta1="<<endl;
cout<<beta1<<endl;
p2=g2*-1+p1*beta1;
cout<<"p2="<<endl;
p2.writeArray();
Po=p2;
Xo=x2;
alfa2=Alpfa(0,fun);
x3=x2+p2*alfa2;
cout<<"x3="<<endl;
x3.writeArray();
k++;
y=Grad(x3,fun);
x1=x3;
}
while((norma(y)>=epsilon)&&(k<=max_step)); // Для п=2 х3 - минимум, т. е. надо задавать k=1
cout<<"norma(y)="<<norma(y)<<endl;
max_step=k-1;
return x3;
}
// Основная программа
void main()
{//1
double e=0.001;
int fun, iter, n;
TMatrix<double> xs, Min;
char answer;
do
{//2
cout<<"1) 2*x^2+2*y^2+2*x*y-x+1"<<endl;
cout<<"2) (x-1)^2+(y-3)^2+4*(z+5)^2"<<endl;
cout<<"Enter number of the chosen function for testing:"<<endl;
cin>>fun;
switch(fun)
{//3
case 1:
n=2;
xs.setSize(n,1);
xs[1]=0;
xs[2]=0;
break;
case 2:
n=3;
xs.setSize(n,1);
xs[1]=4;
xs[2]=-1;
xs[3]=2;
break;
default:cout<<"Such variant of a choice is not possible!"<<endl;
break;
}//3
cout<<"Enter restriction on a maximum quantity of iterations:"<<endl;
cin>>iter;
Min=Daniel(xs,e,iter,fun);
cout<<"\n\nHave received a minimum:"<<endl;
Min.writeArray();// Вывод полученного минимума
cout<<"\nQuantity of iterations: "<<iter<<endl;
cout<<"Will continue? y (yes) or n (no) ?\n";
cin>>answer;
if (answer=='n') break;
}//2
while (1);
}//1
Соседние файлы в папке Лабораторная работа №7