Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
1
Добавлен:
01.05.2014
Размер:
3.67 Кб
Скачать
#include <iostream.h>
#include <math.h>
///точка в двухмерном пространстве
class dot2
{
	private:
		double* x;
		double* p;
		double* grad;
		double** H;
		int n;
	public:
		dot2(int m);
		void input(double*);
		double f1(double k);
		void create_grad();
		void create_H();
		void anti_H();
		void create_p();
		void step();
		int kop();
		void out();
};
dot2::dot2(int m)
{
	n=m;
	x=new double[n];
	p=new double[n];
	grad=new double[n];
	H=new double*[n];
	*H=new double[n];
}
void dot2::input(double* x1)
{
	for (int i=0;i<n;i++)
		*(x+i)=*(x1+i);
}
double dot2::f1(double k)
{
	if(n==1)
		return 100*(*(x+1)+k*(*(p+1))-(*x+k*(*p))*(*x+k*(*p)))*(*(x+1)+k*(*(p+1))-(*x+k*(*p))*(*x+k*(*p)))+(1-(*x+k*(*p)))*(1-(*x+k*(*p)));
	else
		if(n==2)
			return (*x+k*(*p)-1)*(*x+k*(*p)-1)+(*(x+1)+k*(*(p+1))-3)*(*(x+1)+k*(*(p+1))-3)+4*(*(x+2)+k*(*(p+2))+5)*(*(x+2)+k*(*(p+2))+5);
	return 0;
}
void dot2::create_grad()
{
	double d1,d2,xv,h=0.0000001;;
	for(int i=0;i<n;i++)
	{
		xv=*(x+i);
		*(x+i)=*(x+i)-h;
		d1=f1(0);
		*(x+i)=*(x+i)+2*h;
		d2=f1(0);
		*(grad+i)=-(d1+d2)/(2*h);
		*(x+i)=xv;
	}
}
void dot2::create_H()
{
	double d1,d2,d3,xv1,xv2,h1=0.0000001,h2=0.0000001;
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			//if(h1<fabs(*(x+i))) h1
			xv1=*(x+i);
			xv2=*(x+j);
			*(x+i)=*(x+i)+h1;
			*(x+j)=*(x+j)+h2;
			d1=f1(0);
			*(x+i)=xv1;
			d2=f1(0);
			*(x+j)=xv2;
			*(x+i)=*(x+i)+h1;
			d3=f1(0);
			*(x+i)=xv1;
			*(*(H+i)+j)=(d1-d2-d3+f1(0))/(h1*h2);
		}
}
void dot2::create_p()
{
	for(int k=1; k<=n; k++)
	   {
		  double lead=*(*H+k)+k;
	/*      if(fabs(lead)<eps)
		  {
		 cout<<"Ошибка: определитель равен нулю"<<endl;
		 return x;
		  }*/

		  for(int j=k; j<=n; j++)
		  {
			*(*(H+k)+j)/=lead;
		  }
		  *(grad+k)/=lead;
		  for(int i=k+1; i<=n; i++)
		  {
			 double div_lead=(*(*(H+i)+k))/(*(*(H+k)+k));
			 for(j=k; j<=n; j++)
			 {
				(*(*(H+i)+j))-=(*(*(H+k)+j))*div_lead;
			 }
			*(grad+i)-=*(grad+k)*div_lead;
		  }
	   }

	   //обратный ход
	   *(p+n)=*(grad+n);
	   for(k=n-1; k>=1; k--)
	   {
		  double sum=*(grad+k);
		  for(int j=k+1; j<=n; j++)
		  {
			 sum-=(*(*(H+k)+j))*(*(p+j));
		  }

		  *(p+k)=sum;
	   }

}
void dot2::step()
{
	for(int i=0;i<n;i++)
		*(x+i)+=(*(p+i));
}
int dot2::kop()
{
	double e=0.000001,kop1,kop2;
	for(int i=0;i<n;i++)
		kop1+=(*(p+i))*(*(p+i));
	kop1=sqrt(kop1);
	kop2=abs(f1(0)-f1(-1));
	if((kop1<e)&&(kop2<e))
		return 1;
	else return 0;
}
void dot2::out()
{
	for(int i=0;i<n;i++)
		cout<<*(x+i)<<" ";
	cout<<'\n';
}

void main()
{
	double e=0.000001;
	double* x1;
	int n,k=0,s,num;
	cout<<"Viberite funkciyu dlya minimizacii: "<<'\n';
	cout<<"1 - F1(x1,x2)=100(x2-x1^2)^2+(1-x1)^2\n";
	cout<<"2 - F2(x1,x2,x3)=(x1-1)^2+(x2-3)^2+4(x3+5)^2\n";
	cin>>num;
	x1=new double[num+1];
	dot2 X(num+1);
	switch(num)
	{
		case 1:
			cout<<"vvedite koordinati nachalnoy tochki ";
			cin>>x1[0]>>x1[1];
			X.input(x1);
			cout<<"vvedite kolichestvo iteraciy algoritma ";
			cin>>n;
			do
			{
				X.create_grad();
				X.create_H();
				X.create_p();
				X.step();
				s=X.kop();
				k++;
			}
			while((s==0)&&(k<n));
			X.out();
			break;
		case 2:
			cout<<"vvedite koordinati nachalnoy tochki ";
			cin>>x1[0]>>x1[1]>>x1[2];
			X.input(x1);
			cout<<"vvedite kolichestvo iteraciy algoritma ";
			cin>>n;
			do
			{
				X.create_grad();
				X.create_H();
				X.create_p();
				X.step();
				s=X.kop();
				k++;
			}
			while((s==0)&&(k<n));
			X.out();
			break;
		default:
			cout<<"takoy variant otsutstvuet\n";
	}
}
Соседние файлы в папке Лабораторная работа №61