Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа №7
.CPP#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();
}
Соседние файлы в предмете Методы оптимизации