Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабораторная работа №7

.CPP
Скачиваний:
4
Добавлен:
01.05.2014
Размер:
5.97 Кб
Скачать
#include<math.h>
#include<conio.h>
#include<iostream.h>
//#include<stdio.h>

//4x12 + 3x22 - 4x1x22 + x1	( 0 ; 0 )	( -1/8 ;  3/80000000)
//М4 - метод Дэвидона - Флетчера - Пауэлла;

double e = 0.00001;

double y(double*);
double dy(double*, double*);
double* Swenn(double*, double*);
double* Boltsano(double*, double*);
double* Grad(double*);
double Norma(double*);
double* Rasnost(double*, double*);
double* Gamma(double*, double*);
double* S(double*, double*, double*);
double* Matrix(double*, double*, double*, double*, int);
double* DFP(double*);

double y(double *Pointer)		// функция от альфа
{
	double res, x[2] = {*Pointer++ , *Pointer};
    res = 4*x[0]*x[0] + 3*x[1]*x[1] - 4*x[0]*x[1]*x[1] + x[0];
	return(res);
}

double dy(double *Pointer, double *Pointer2) //задаем производную функции y(x)
{
 double x[2] = {*Pointer++, *Pointer}, res;
 double p[2] = {*Pointer2++, *Pointer2};
 double x1[2] = {x[0]+e*p[0], x[1]+e*p[1]};
 res = (y(x1) - y(x))/e;
 return(res);
}


double* Swenn(double *Pointer, double *Pointer2) //локализуем интервал [A,B]
{
 double x[2] = {*Pointer++, *Pointer}, h = 0.5, res[4];
 double p[2] = {*Pointer2++, *Pointer2--};

 if (dy(x, p) > 0)
  {
   p[0] = -p[0];
   p[1] = -p[1];
   *Pointer2 = -*Pointer2++;
   *Pointer2 = -*Pointer2--;
  }

 int sign = 1;
 if (dy(x, p) < 0)
  sign = -sign;
 do
  {
   h = 2*h;
   x[0] = x[0] + h*p[0];
   x[1] = x[1] + h*p[1];
  }
 while(sign * dy(x, p) > 0);

 res[0] = x[0] - h*p[0];
 res[1] = x[1] - h*p[1];
 res[2] = x[0];
 res[3] = x[1];
 return(res);
}

double* Boltsano(double *Pointer, double *Pointer2)   //методом Больцано находим альфа
{
 double X[2] = {*Pointer++, *Pointer++}, p[2] = {*Pointer2++, *Pointer2++};
 Pointer = Swenn(X, p);
 double A[2] = {*Pointer++, *Pointer++}, B[2] = {*Pointer++, *Pointer};

 while((fabs(dy(X, p)) > e) )
  {
   X[0] = (A[0] + B[0]) / 2;
   X[1] = (A[1] + B[1]) / 2;
   if (dy(X, p) > 0)
    {
     B[0] = X[0];
     B[1] = X[1];
    }
   else
    {
     A[0] = X[0];
     A[1] = X[1];
    }
  }
 double res[2] = {(B[0] + A[0])/2, (B[1] + A[1])/2};
 return(res);
}

double* Grad(double *Pointer)  //находим градиент функции y(x)
{
 double x[2] = {*Pointer++, *Pointer};
 double Res[2];
 Res[0] = 8*(x[0] - 5);
 Res[1] = 2*(x[1] - 6);
 if ((Res[0] > 100) && (Res[1] > 100))
  {
   Res[0] = Res[0]/100;
   Res[1] = Res[1]/100;
  }
 return(Res);
}


double Norma(double *Pointer)   //находим норму вектора X
{
 double x[2] = {*Pointer++, *Pointer}, Res;
 Res = sqrt(x[0]*x[0] + x[1]*x[1]);
 return(Res);
}


double* Rasnost(double *Pointer, double *Pointer2)
{
	double x1[2]={*Pointer++,*Pointer}, x2[2]={*Pointer2++,*Pointer}, res[2];

	res[0]=x2[0] - x1[0];
	res[1]=x2[1] - x1[1];

	return(res);
}

double* Gamma(double *Pointer, double *Pointer2)
{
	double x1[2]={*Pointer++,*Pointer}, x2[2]={*Pointer2++,*Pointer2}, res[2];

	res[0] = Grad(x2)[0] - Grad(x1)[0];
	res[1] = Grad(x2)[1] - Grad(x1)[1];

	return(res);
}

double* S(double *Pointer1, double *Pointer2, double *Pointer3)
{
	double A1[2]={*Pointer1++,*Pointer1}, A2[2]={*Pointer2++,*Pointer2}, G[2]={*Pointer3++, *Pointer3};
	double res[2];

	res[0] = A1[0]*G[0] + A1[1]*G[1];
	res[1] = A2[0]*G[0] + A2[1]*G[1];

	return(res);
}

double* Matrix(double *Pointer, double *Pointer1, double *Pointer2, double *Pointer3, int f)
{
	double X1[2]={*Pointer++, *Pointer}, X2[2]={*Pointer1++, *Pointer1}, A1[2]={*Pointer2++, *Pointer2}, A2[2]={*Pointer3++, *Pointer3};
	double s[2], G[2], X21[2], temp1[4], temp2[4], t1, t2, res1[2], res2[2];
    
	Pointer=Rasnost(X1, X2);
	X21[0] = *Pointer++;
	X21[1] = *Pointer;

	Pointer=Gamma(X1, X2);
	G[0] = *Pointer++;
	G[1] = *Pointer;

	Pointer=S(A1, A2, G);
	s[0] = *Pointer++;
	s[1] = *Pointer;

	temp1[0] = X21[0]*X21[0];
	temp1[1] = X21[0]*X21[1];
	temp1[2] = X21[1]*X21[0];
	temp1[3] = X21[1]*X21[1];

	temp2[0] = s[0]*s[0];
	temp2[1] = s[0]*s[1];
	temp2[2] = s[1]*s[0];
	temp2[3] = s[1]*s[1];

	t1 = X21[0]*G[0] + X21[1]*G[1];
	t2 = s[0]*G[0] + s[1]*G[1];

	res1[0] = A1[0] +temp1[0]/t1 - temp2[0]/t2;
	res1[1] = A1[1] +temp1[1]/t1 - temp2[1]/t2;
	res2[0] = A2[0] +temp1[2]/t1 - temp2[2]/t2;
	res2[1] = A2[1] +temp1[3]/t1 - temp2[3]/t2;

	if (f != 2)
	{
		return(res1);
	}
	else
	{
		return(res2);
	}
}

double* DFP(double *Pointer)
{
	double X1[2] = {*Pointer++,*Pointer};
	double X2[2], X3[2], p[2], k = 1, E1[2]={1,0},E2[2]={0,1}, *A1, *A2, *t1, *t2, res[2];

	while(1)
	{
	//cout<<X3[0]<<endl;
		if (k == 1)
		{
	  //          *A1++ = 1;
	//	    *A1 = 0;
			

	//	    *A2++ = 0;
	//	    *A2 = 1;

            A1=E1;
            A2=E2;

		    Pointer = Grad(X1);             //находим точку X2
                    p[0] = -*Pointer++;
                    p[1] = -*Pointer;

			Pointer = Boltsano(X1, p);
 			X2[0] = *Pointer++;
 			X2[1] = *Pointer;

			X3[0] = X2[0];
			X3[1] = X2[1];
		}
		else
		{
			t1 = A1;
			t2 = A2;

			A1 = Matrix(X1, X2, t1, t2, 1);
			A2 = Matrix(X1, X2, t1, t2, 2);

			Pointer = Grad(X2);
			p[0] = - (A1[0]*(*Pointer++) + A1[1]*(*Pointer));
			p[1] = - (A2[0]*(*Pointer++) + A2[1]*(*Pointer));

			Pointer = Boltsano(X2, p);
 			X3[0] = *Pointer++;
			X3[1] = *Pointer;
			
	//	cout<<k<<endl;
			k++;
		}

		if (Norma(Grad(X3)) < e)// || (k>100))
		{

			res[0] = X3[0];
			res[1] = X3[1];
			return(res);
		}
		else
		{
			

			X1[0] = X2[0];
			X1[1] = X2[1];

			X2[0] = X3[0];
			X2[1] = X3[1];
		}
	}


}

void main()
{
 clrscr();
	double Xo[2] = {0, 0}, *Pointer, Min[2];

	cout << " starting point [" << Xo[0] << "," << Xo[1] << "]" <<endl;
    Pointer = DFP(Xo);          //находим минимум из точки Xo
    Min[0] = *Pointer++;
    Min[1] = *Pointer;
    cout << "[" << Min[0] << ", " << Min[1] << "]" << endl << endl;;

	getch();
}