Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторные работы 1-5 / LABA5 / LAB5GOOD
.CPP#include <iostream.h>
#include <conio.h>
#include <math.h>
/****************************** Klass Vector ********************************/
class Vector
{
public:
Vector(int Size);
Vector(const Vector& v);
~Vector();
int size() const;
double& Vector::operator[](int N);
double Vector::operator[](int N) const;
void Summa(const Vector& a, const Vector& b);
void Razn(const Vector& a, const Vector& b);
Vector Scal(Vector x, double d);
double Umn(const Vector& a, const Vector& b);
Vector& operator=(const Vector& a);
void Write() const;
Vector Grad(const Vector& x);
/******************* Ispolsuemie algoritmi iz Lab4 ***************************/
void Swenn4(const Vector& x, Vector& p, double& ala, double& alb, int& iter);
double ZS2(Vector& x, Vector& p, double& ala, double& alb, double& E, int& iter);
double Davidon(Vector& x, Vector& p, double& ala, double& alb, double& E, int& iter);
Vector Evec(int n, int Num);
double Norma(Vector x);
Vector GZ_3(Vector& x, double E, int maxiter, int& iter, int& bool, int method);//!!!
/*********************** Operacii nad vectorami ******************************/
Vector operator+(const Vector& a)
{
Vector s(nSize);
s.Summa(*this, a);
return s;
}
Vector operator-(const Vector& a)
{
Vector s(nSize);
s.Razn(*this, a);
return s;
}
/*Vector Minus(const Vector& a)
{
Vector s(nSize);
s.Razn(*this, a);
return s;
}*/
double operator*(const Vector& a)
{
double w;
Vector s(nSize);
w = s.Umn(*this, a);
return w;
}
/*double Umnoj(const Vector& a)
{
double w;
Vector s(nSize);
w=s.Umn(*this, a);
return w;
}*/
void operator*=(double d)
{
for (int i = 0; i < nSize; i++)
Coord[i] *= d;
}
/*void ZvRavno(double d)
{
for (int i =0; i<nSize; i++)
Coord[i]*=d;
}*/
private:
double* Coord;
int nSize;
};
Vector::Vector(int Size)
{
nSize = Size;
Coord = new double[Size];
}
Vector::Vector(const Vector& v)
{
nSize = v.size();
Coord = new double[nSize];
for (int i = 0; i < nSize; i++)
Coord[i] = v[i];
}
Vector::~Vector()
{
delete[] Coord;
}
int Vector::size() const
{
return nSize;
}
double& Vector::operator[](int N)
{
return *&Coord[N];
}
double Vector::operator[](int N) const
{
return Coord[N];
}
Vector Vector::Scal(Vector x, double d)
{
int i = x.size();
Vector W(i);
for(int j=0; j<i; j++)
W[j] = x[j]*d;
return W;
}
void Vector::Summa(const Vector& a, const Vector& b)
{
int s = a.size();
int i;
if ((s = b.size()) != 0 )
{
for (i = 0; i < s; i++)
{
Coord[i] = a[i] + b[i];
}
}
else
{
cout<<"ERROR!"<<endl;
}
}
void Vector::Razn(const Vector& a, const Vector& b)
{
int s = a.size();
int i;
if ((s = b.size()) != 0 )
{
for (i = 0; i < s; i++)
{
Coord[i] = a[i] - b[i];
}
}
else
{
cout<<"ERROR!"<<endl;
}
}
double Vector::Umn(const Vector& a, const Vector& b)
{
int s = a.size();
//int i;
double Um=0;
if ((s = b.size()) != 0 )
{
for (int i = 0; i < s; i++)
{
Coord[i] = a[i] * b[i];
Um = Um + Coord[i];
}
}
return Um;
}
Vector& Vector::operator =(const Vector& a)
{
for (int i = 0; i < nSize; i++)
{
Coord[i] = a.Coord[i];
}
return *this;
}
void Vector::Write() const
{
cout<<"This is vector:"<<endl;
for (int i = 0; i < nSize; i++)
{
cout<<Coord[i]<<endl;
};
}
/************************** Testovie funkcii *********************************/
double F (Vector t)
{
double result = 0;
if (t.size() == 2)
result = pow(t[1]-t[0]*t[0], 2) + pow(1-t[0], 2);
if (t.size() == 3)
result = (t[0]-1)*(t[0]-1) + (t[1]-3)*(t[1]-3) + 4*(t[2]+5)*(t[2]+5);
//result = 3*(t[0]-4)*(t[0]-4) + 5*(t[1]+3)*(t[1]+3) + 7*(2*t[2]+1)*(2*t[2]+1);
if (t.size() == 4)
//result = t[0]-10*t[2]+5*(t[2]-t[3])*(t[2]-t[3])+pow(t[1]-2*t[2], 4)+10*pow(t[0]-t[3], 4);
result = 100*pow(t[1]-t[0]*t[0], 2) + (1-t[0])*(1-t[0]) + 90*pow(t[3]-t[2]*t[2], 2) + pow(1-t[2], 3) + 10.1*(t[1]-1)*(t[1]-1) + (t[3]-1)*(t[3]-1) + (t[1]-1)*(t[3]-1);
return result;
}
/********************* 4astnaya proizvodnaya po Xi ***************************/
double ChP(Vector x, int i)
{
int t = x.size();
double w = -1000; //!!!
double h = 0.000001;
Vector q(t);
if (t >= i)
w = ( F(x + q.Scal(q.Evec(t, i), h)) - F(x - q.Scal(q.Evec(t, i), h)) )/(2*h);
return w;
}
/**************************** Gradient ***************************************/
Vector Vector::Grad(const Vector& x)
{
int i = x.size();
Vector w(i);
for (int j = 1; j<=i; j++)
{
w[j-1] = ChP(x, j);
}
return w;
}
/*************** 1-aya testovaya funkciya-Metod Swenna 4 *********************/
void Vector::Swenn4(const Vector& x, Vector& p, double& ala, double& alb, int& iter)
{
int r = x.size(),// Vektor skol'ki peremennih?
iter=0; // Koli4estvo iteraciy
Vector G(r); // Opredelenie
G = G.Grad(x); // Vi4islenie gradienta v na4al'noy to4ke
if ((G * p) > 0) // Proverka napravlenia ubivania functsii...
{
p*=-1;
//t=-1;
//p=p.Scal(p, t);
}
double f1, f2, al = 0.000001;
Vector x1(r);
Vector Pro(r);
x1 = x;
f1 = G * p; // Proizvodnaya v na4al'noy to4ke po napravleniyu "p"
do // Dvigaemsya v napravlenii ubivaniya funkcii
{
al = al*2; // Udvaivaem shag
Pro = Pro.Scal(p, al); // Ispol'suem peremennuyu "Pro" dlya hraneniya "al*p"
x1 = x1 + Pro; // Xk+1 = Xk + ALPHAk * Pk
G = G.Grad(x1); // Vi4islenie gradienta v novoy to4ke
f2 = G * p; // Proizvodnaya v novoy to4ke po napravleniyu "p"
iter++;
}
while (f1*f2 > 0); // Proverka KOP
ala=al/2; // Fiksiruem na4al'niy interval 4erez shagi
alb=al;
}
/************ 2-aya testovaya funkciya-Metod Zolotogo Se4eniya 1 ************/
double Vector::ZS2(Vector& x, Vector& p, double& ala, double& alb, double& E, int& iter)
{
int r = x.size(),// Vektor skol'ki peremennih?
iter=0; // Koli4estvo iteraciy
double al1, al2, f1, f2;
Vector G(r);
Vector x1(r);
Vector x2(r);
al1=ala+0.61803398875*fabs(alb-ala);
do
{
al2=ala+alb-al1;
x1=x+G.Scal(p,al1);
f1=F(x1);
x2=x+G.Scal(p,al2);
f2=F(x2);
if ((al1<al2)&&(f1<f2))
alb=al2;
if ((al1<al2)&&(f1>=f2))
{
ala=al1;
al1=al2;
}
if ((al1>al2)&&(f1<f2))
ala=al2;
if ((al1>al2)&&(f1>=f2))
{
alb=al1;
al1=al2;
}
iter++;
}
while (iter<5);
}
/*************** *********************/
Vector Vector::Evec(int n, int Num) // - koordinatniy ort
{ // dlinoy 'n'
Vector W(n); // i 1-tsey na 'Num'
int i=0;
while (i<n)
{
W[i] = 0;
i++;
}
W[Num-1] = 1;
return W;
}
/*************** *********************/
double Vector::Norma(Vector x)
{
int i = x.size();
double d=0;
for (int j = 0; j < i; j++)
d = d + x[j]*x[j];
return sqrt(d);
}
/*************** *********************/
double Vector::Davidon(Vector& x, Vector& p, double& ala, double& alb, double& E, int& iter)
{
double a, b, bb, c, d, dd, help1, help2, Q, S;
int r = x.size();
Vector xa(r);
Vector xb(r);
Vector xc(r);
Vector xd(r);
a = al1;
b = (al1+al2)/2;
c = al2;
xa = x + xa.Scal(p, a);
xb = x + xb.Scal(p, b);
xc = x + xc.Scal(p, c);
help1 = ( F(xa)*(b*b-c*c) + F(xb)*(c*c-a*a) + F(xc)*(a*a-b*b) );
help2 = (F(xa)*(b-c) + F(xb)*(c-a) + F(xc)*(a-b));
if (help2 == 0)
help2 = 0.0000001;
d = 0.5*help1/help2;
xd = x + xd.Scal(p, d);
while ((fabs((d-b)/b) >= E) || (fabs(F(xd)-F(xb))/F(xb) >= E ))
{
if (b<d)
{
if (F(xb)<F(xd))
{
c = d;
b = (a+c)/2;
}
else
{
a = b;
b = (a + c)/2;
}
}
if (b>d)
{
if (F(xb)>F(xd))
{
c = b;
b = (a + c)/2;
}
else
{
a = d;
b = (a + c)/2;
}
}
xa = x + xa.Scal(p, a);
xb = x + xb.Scal(p, b);
xc = x + xc.Scal(p, c);
help1 = (F(xa)-F(xb))*(b-c)*(c-a);
help2 = (F(xa)*(b-c) + F(xb)*(c-a) + F(xc)*(a-b));
if (help2 == 0)
break; // Delenie na nol'
d = (a+b)/2 + 0.5*(help1/help2);
xd = x + xd.Scal(p, d);
bb = b;
dd = d;
}
b = bb;
d = dd;
return (b + d)/2;
}
/*************** *********************/
Vector Vector::GZ_3(Vector& x, double E, int maxiter, int& iter, int& bool, int method)
{
int r = x.size();
Vector p(r); //napravlenie
Vector G(r); //vspomogatel'naya
Vector t(r); //dubliruet 'x'
double w, al, a, b, k;
int y=0;
t = x;
bool = 0;
while ( ( Norma(G.Grad(t)) >= E ) && ( y < maxiter ) )
{
k = Norma(G.Grad(t));
for (int i = 1; i<=r; i++)
{
w = ChP(t, i);
p = p.Scal(Evec(r,i), w);
G.Swenn(t, p, a, b);
if (method == 1)
al = G.ZS1(t, p, a, b, E); //alpha i-oe
if (method == 2)
al = G.Pauell(t, p, a, b, E); //alpha i-oe
t = t + G.Scal(p, al);
}
y++;
}
if (Norma(G.Grad(t)) < E)
bool = 1;
iter = y;
return t;
}
/***********************************************/
void main()
{
clrscr();
double E;
int it=0, maxit, tochnost;
int choice, razmer, method, itogoiter=0;
char otvet, dalshe;
cout<<"Dannaia programma ispol'zuet metod GAUSSA-ZEIDELIA"<<endl;
cout<<"dlia nahojdenia minimuma funktsii."<<endl;
cout<<"Predusmotren vibor metoda promejutochnih raschetov (ZS-1, Pauell)"<<endl;
cout<<endl;
cout<<"Viberite functsiu:"<<endl;
cout<<"1. f(x1,x2) = (x2-x1x1)(x2-x1x1) + (1-x1)(1-x1);"<<endl;
cout<<"2. f(x1,x2,x3) = (x1-1)(x1-1) + (x2-3)(x2-3) + 4(x3+5)(x3+5)"<<endl;
//cout<<"3. f(x1,x2,x3,x4) = x1 - 10x2 + 5(x3-x4) + (x2-2x3)^4 + 10(x1-x4)^4"<<endl;
cout<<"3. f(x1,x2,x3,x4) = 100(x2-x1x1)^2 + (1-x1)^2 + 90(x4-x3x3)^2 + (1-x3)^3 + "<<endl;
cout<<" + 10.1(x2-1)^2 + (x4-1)^2 + 19.8(x2-1)(x4-1)"<<endl;
cin>>choice;
razmer = choice + 1;
Vector x(razmer);
for (int i = 0; i < razmer; i++)
x[i] = 0;
cout<<"Po umolchaniu nachalnaia tochka imeet koordinati x[i]=0.5. Izmenit'? (y/n)"<<endl;
otvet = getch();
if (otvet == 'y')
for (int i = 0; i < razmer; i++)
{
cout<<"Zadaite "<<i+1<<" koordinatu: ";
cin>>x[i];
}
Vector Q3(razmer);
int pomoshnik = 0;
do
{
cout<<endl;
cout<<"Viberite metod rascheta:"<<endl;
cout<<"1. Metod Zolotogo Sechenia (1);"<<endl;
cout<<"2. Metod Pauella"<<endl;
cin>>method;
cout<<"Vvedite max kol-vo iteratsii: ";
cin>> maxit;
cout<<"Vvedite pogreshnost' (E = 0.00001 - 0.0000000001) : ";
cin>>E;
cout<<endl;
if (pomoshnik > 0)
{
x = Q3;
cout<<"Izmenit' nachal'nuiu tochku? (y/n)"<<endl;
otvet = getch();
if (otvet == 'y')
for (int i = 0; i < razmer; i++)
{
cout<<"Zadaite "<<i+1<<" koordinatu: ";
cin>>x[i];
}
};
Q3 = Q3.GZ_3(x, E, maxit, it, tochnost, method);
cout<<"kolichestvo iteratsii v dannom shage: "<<it;
itogoiter = itogoiter + it;
cout<<", vsego: "<<itogoiter<<endl;
if (tochnost == 1)
{
cout<<"tochnost' DOSTIGNUTA... "<<endl;
}
else
{
cout<<"tochnost' NE dostignuta... "<<endl;
}
Q3.Write();
cout<<"Prodoljit' rascheti? (y/n)"<<endl;
dalshe = getch();
pomoshnik++;
}
while (dalshe != 'n');
}