Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа №9 / LABA9
.CPP#include <conio.h>
#include <iostream.h>
#include <math.h>
// Подключаем класс для работы с матрицами
#include "matrix.cpp"
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 x[1]*x[1]+2*x[2]*x[2]-2*x[1]*x[2]+x[2];
break;
case 3:
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 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> fksi(TMatrix<double> x, int &vhojd)
{
TMatrix<double> ksi;
int n=x.getSizeRow();
ksi.setSize(n,1);
if (n==2)
{
if (vhojd==1)
{
ksi[1]=1;
ksi[2]=0;
}
if (vhojd==2)
{
ksi[1]=1;
ksi[2]=1;
}
if (vhojd==3)
{
ksi[1]=0;
ksi[2]=1;
}
if (vhojd==4)
{
ksi[1]=-1;
ksi[2]=1;
}
if (vhojd==5)
{
ksi[1]=-1;
ksi[2]=0;
}
if (vhojd==6)
{
ksi[1]=-1;
ksi[2]=-1;
}
if (vhojd==7)
{
ksi[1]=0;
ksi[2]=-1;
}
if (vhojd==8)
{
ksi[1]=1;
ksi[2]=-1;
}
if (vhojd>8) vhojd=1;
}
if (n==3)
{
if (vhojd==1)
{
ksi[1]=1;
ksi[2]=0;
ksi[3]=0;
}
if (vhojd==2)
{
ksi[1]=-1;
ksi[2]=0;
ksi[3]=0;
}
if (vhojd==3)
{
ksi[1]=0;
ksi[2]=1;
ksi[3]=0;
}
if (vhojd==4)
{
ksi[1]=0;
ksi[2]=-1;
ksi[3]=0;
}
if (vhojd==5)
{
ksi[1]=0;
ksi[2]=0;
ksi[3]=1;
}
if (vhojd==6)
{
ksi[1]=0;
ksi[2]=0;
ksi[3]=-1;
}
if (vhojd>6) vhojd=1;
}
return ksi;
}
//Алгоритм поиска с возвратом при неудачном шаге
TMatrix<double> SearchWithReturn(TMatrix<double> x0,double eps,int &iter,int fun)
{//1
TMatrix<double> p, ksi, x;
double alfa=0.5, beta=0.1;
int n=x0.getSizeRow();
p.setSize(n,1);
ksi.setSize(n,1);
x.setSize(n,1);
iter=0;
int k=0, j=0, M=10,vhojd=1;
while(1)
{//2
iter++;
cout<<"Iteraciya "<<iter<<endl;//////////////////////////////////////
//Ш1. Получение случайного нормированного вектора:
ksi=fksi(x0,vhojd);
cout<<"ksi="<<endl;/////////////////////////////////////////////////
ksi.writeArray();///////////////////////////////////////////////////
p=ksi*(1/norma(ksi));
cout<<"p="<<endl;///////////////////////////////////////////////////
p.writeArray();/////////////////////////////////////////////////////
//Ш2 & Ш3.
if(f(x0+p*alfa,fun)<f(x0,fun))
{
x=x0+p*alfa;
x0=x;
cout<<"y(x)="<<f(x,fun)<<endl;//////////////////////////////////
k++; //Удачные испытания
}
//Ш4.
else
{
j++;
vhojd++;
cout<<"vhojd="<<vhojd<<endl;////////////////////////////////////
if ((j==M)&(alfa<=eps)) return x;
if ((j==M)&(alfa>eps))
{
alfa=alfa*beta;
j=0;
}
}
}//2
}//1
// Основная программа
void main()
{//1
double e=0.0000001;
int fun, iter=0, 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^2+2*y^2-2*x*y+y"<<endl;
cout<<"3) (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=2;
xs.setSize(n,1);
xs[1]=1;
xs[2]=0;
break;
case 3:
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
Min=SearchWithReturn(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
Соседние файлы в папке Лабораторная работа №9