Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
4
Добавлен:
01.05.2014
Размер:
5.14 Кб
Скачать
#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> IP(TMatrix<double> x,int fun)
{
	TMatrix<double> z1,z2,e1,e2,e3;
	double h=0.5;
	int i=1, k=1, n;

	n=x.getSizeRow();

	e1.setSize(x.getSizeRow(),x.getSizeCol());
	e2.setSize(x.getSizeRow(),x.getSizeCol());
	e3.setSize(x.getSizeRow(),x.getSizeCol());

	if (n==2)
	{
	e1[1]=1; e1[2]=0;
	e2[1]=0; e2[2]=1;
	}
	else
	{
	e1[1]=1; e1[2]=0; e1[3]=0;
	e2[1]=0; e2[2]=1; e2[3]=0;
	e3[1]=0; e3[2]=0; e3[3]=1;
	}

	z1.setSize(x.getSizeRow(),x.getSizeCol());
	z2.setSize(x.getSizeRow(),x.getSizeCol());
	
	z1=x;
	do
	{
		do
		{
			if (k != 1)
			{
				if (k%2==0) h=-h;
			
				if ((k+1)%2 == 0) h=-0.1*h;
					
			}
		z2=z1+e1*h;
		k++;
		}
		while(f(z2,fun)>f(z1,fun));
	k=1;
	z1=z2;
	i++;
		if (i==2) e1=e2;
		if (i==3) e1=e3;
	
	}
	while (i<=n);
	i=1;
	if (f(z2,fun)>f(x,fun)) cout<<"Error!!!"<<endl;

	return z2;
}

// Ускоряющий поиск
TMatrix<double> UP(TMatrix<double> x,TMatrix<double> y,int fun)
{
	TMatrix<double> z1,z2,z3;
	double alfa=1;

	z1.setSize(x.getSizeRow(),x.getSizeCol());
	z2.setSize(x.getSizeRow(),x.getSizeCol());
	z3.setSize(x.getSizeRow(),x.getSizeCol());

	do
	{
	z1=x;
	z2=y;
	z3=z2+(z2-z1)*alfa;
	alfa=alfa-0.1;
	}
	while (f(z3,fun)>f(x,fun));

	return z3;
}

// Метод Хука-Дживса (Конфигураций)
TMatrix<double> Configurations(TMatrix<double> x,double eps,int &max_step,int fun)
{
	// Переменные
	double epsilon=eps;
	TMatrix<double> x1, x2, x3, x4,y;
	int k=1;

	// Установка размера матриц и векторов

	x1.setSize(x.getSizeRow(),x.getSizeCol());
	x2.setSize(x.getSizeRow(),x.getSizeCol());
	x3.setSize(x.getSizeRow(),x.getSizeCol());
	x4.setSize(x.getSizeRow(),x.getSizeCol());
	y.setSize(x.getSizeRow(),x.getSizeCol());

	x1=x;

	
		cout<<"				Iteraciya	"<<k<<endl;
		cout<<"x1="<<endl;
		x1.writeArray();
		cout<<"y1= "<<f(x1,fun)<<endl;

		x2=IP(x1,fun);
		cout<<"x2="<<endl;
		x2.writeArray();
		cout<<"y2= "<<f(x2,fun)<<endl;
	do
	{
		x3=UP(x1,x2,fun);
		cout<<"x3="<<endl;
		x3.writeArray();
		cout<<"y3= "<<f(x3,fun)<<endl;

		x1=x2;

		x4=IP(x3,fun);
		cout<<"x4="<<endl;
		x4.writeArray();
		cout<<"y4= "<<f(x4,fun)<<endl;

		x2=x4;

		k++;
		cout<<"				Iteraciya	"<<k<<endl;
		y=Grad(x4,fun);
	}
	while((norma(y)>=epsilon)&&(k<=max_step));

	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^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]=1;
					xs[2]=1;
					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
			cout<<"Enter restriction on a maximum quantity of iterations:"<<endl;
			cin>>iter;
			Min=Configurations(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
Соседние файлы в папке Лабораторная работа №8