Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
3
Добавлен:
01.05.2014
Размер:
5.04 Кб
Скачать
#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