
Добавил:
Medi
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
// l_5.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <math.h>
using namespace std;
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 Sum(const Vector& a, const Vector& b);
void Subtraction(const Vector& a, const Vector& b);
Vector Scal(Vector x, double d);
double Mult(const Vector& a, const Vector& b);
Vector& operator=(const Vector& a);
Vector function(Vector& x, double E, int method, int & it);
void Write() const;
Vector Grad(const Vector& x);
/***************Lab3***************/
void Swenn(const Vector& x, Vector& p, double& ala, double& alb);
//double ZS1(Vector& x, Vector p, double al1, double al2);
double ZS1(Vector& x, Vector p, double al1, double al2, double E, int & it);
double Powell(Vector& x, Vector p, double al1, double al2, double E, int & it);
/***************Lab4***************/
Vector Ort(int n, int Num);
double Norma(Vector x);
Vector GZ_3(Vector& x, double E, int maxiter, int& iter, int& boo, int method, int razmer);
Vector operator+(const Vector& a)
{
Vector s(nSize);
s.Sum(*this, a);
return s;
}
Vector operator-(const Vector& a)
{
Vector s(nSize);
s.Subtraction(*this, a);
return s;
}
double operator*(const Vector& a)
{
double w;
Vector s(nSize);
w = s.Mult(*this, a);
return w;
}
void operator*=(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::Sum(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::Subtraction(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::Mult(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;
};
}
double F (Vector t)
{
double result = 0;
if (t.size() == 2)
result = t[0]*t[0]+3*t[1]*t[1]+2*t[0]*t[1];
if (t.size() == 3)
result = (t[0]-1)*(t[0]-1) + (t[1]-3)*(t[1]-3) + 4*(t[2]+5)*(t[2]+5);
if (t.size() == 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;
}
double Diff(Vector x, int i)
{
int t = x.size();
double w = 0;
double h = 0.000001;
Vector q(t);
if (t >= i)
w = ( F(x + q.Scal(q.Ort(t, i), h)) - F(x - q.Scal(q.Ort(t, i), h)) )/(2*h);
return w;
}
Vector Vector::Grad(const Vector& x)
{
int i = x.size();
Vector w(i);
for (int j = 1; j<=i; j++)
{
w[j-1] = Diff(x, j);
}
return w;
}
void Vector::Swenn(const Vector& x, Vector& p, double& ala, double& alb)
{
int r = x.size();
Vector G(r);
G = G.Grad(x); // Проверка направления на убывание функции
if ((G * p) > 0)
{
p*=-1;
}
double f1, f2, al = 0.000001;
Vector x1(r);
Vector x2(r);
x1 = x;
f1 = G * p;
do
{
al = al*2;
G = G.Scal(p, al);
x2 = x1 + G;
G = G.Grad(x2);
f2 = G * p;
}
while (f1*f2 > 0);
if((G * p) > 0)
{
alb = al;
ala = al/2;
}
else
{
alb = al/2;
ala = al;
}
}
double Vector::ZS1(Vector& x, Vector p, double al1, double al2, double E, int & it)
{
double l, m, f1, f2, help1, help2;
int j=0;
l = al1 + 0.38196601125*fabs(al1-al2);
m = al1 + 0.61803398875*fabs(al1-al2);
int r = x.size();
Vector G(r);
Vector x1(r);
Vector x2(r);
while ( (fabs(al1-al2) >= E) || (fabs(f1-f2) >= E) )
{
it++;
j = j + 1;
x1 = x + G.Scal(p, l);
f1 = F(x1);
x2 = x + G.Scal(p, m);
f2 = F(x2);
if (f1 < f2)
{
al2 = m;
m = l;
l = al1 + 0.38196601125*fabs(al1-al2);
}
if (f1 >= f2)
{
al1 = l;
l = m;
m = al1 + 0.61803398875*fabs(al1-al2);
}
}
return (al1+al2)/2;
}
Vector Vector::Ort(int n, int Num)
{
Vector W(n);
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::Powell(Vector& x, Vector p, double al1, double al2, double E, int & it)
{
double a, b, c, d, help1, help2;
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 ))
{
it++;
if( F(xb) > F(xd) )
{
if(b > d)
{
c = b;
}
else
{
a = b;
}
b = d;
}
else
{
if(b > d)
{
a = d;
}
else
{
b = d;
}
}
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);
}
return (b + d)/2;
}
Vector Vector::GZ_3(Vector& x, double E, int maxiter, int& iter, int& boo, int method, int razmer)
{
int r = x.size();
Vector p(r);
Vector G(r);
Vector t(r);
double w, al, a, b, k;
int y=0;
t = x;
boo = 0;
int it = 0;
while ( ( Norma(G.Grad(t)) >= E ) && ( y < maxiter ) )
{
k = Norma(G.Grad(t));
for (int i = 1; i<=r; i++)
{
w = Diff(t, i);
p = p.Scal(Ort(r,i), w);
G.Swenn(t, p, a, b);
if (method == 1)
al = G.ZS1(t, p, a, b, E, it); //alpha i-oe
if (method == 2)
al = G.Powell(t, p, a, b, E, it); //alpha i-oe
t = t + G.Scal(p, al);
}
y++;
}
if (Norma(G.Grad(t)) < E)
boo = 1;
iter = y;
return t;
}
Vector Vector::function(Vector& x, double E, int method,int & it)
{
int r = x.size();
Vector p(r); //napravlenie
Vector G(r); //vspomogatel'naya
Vector t(r); //dubliruet 'x'
double al, a, b, k;
int y=0;
t = x;
p[0]=2; p[1]=3;
G.Swenn(t, p, a, b);
if (method == 1)
al = G.ZS1(t, p, a, b, E, it); //alpha i-oe
if (method == 2)
al = G.Powell(t, p, a, b, E, it); //alpha i-oe
t = t + G.Scal(p, al);
return t;
}
void main()
{
double E;
int it=0, maxit, tochnost;
int choice, method, countiter=0;
char answer,razmer, next;
cout<<"Dannaia programma ispolzuet metod Gaussa Zeidelia"<<endl;
cout<<"dlya nahojdenia minimuma funktsii."<<endl;
cout<<"Predusmotren vibor metoda promejutochnih raschetov (ZS-1, Powell)"<<endl;
cout<<endl;
cout<<"Viberite functsiu:"<<endl;
cout<<"1. f(x1,x2) = x1^2+3*x2^2+2*x0*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) = 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. Izmenit'? (y/n)"<<endl;
answer = getch();
if (answer == 'y')
for (int i = 0; i < razmer; i++)
{
cout<<"Zadaite "<<i+1<<" koordinatu: ";
cin>>x[i];
}
Vector Q3(razmer);
int current = 0;
do
{
cout<<endl;
cout<<"Viberite metod rascheta:"<<endl;
cout<<"1. Metod Zolotogo Sechenia-1;"<<endl;
cout<<"2. Metod Powella"<<endl;
cin>>method;
cout<<"Vvedite max kol-vo iteratsii: ";
cin>> maxit;
cout<<"Vvedite pogreshnost' (E = 0.00001 - 0.0000000001) : ";
cin>>E;
cout<<endl;
if (current > 0)
{
x = Q3;
cout<<"Izmenit nachalnuiu tochku? (y/n)"<<endl;
answer = getch();
if (answer == 'y')
for (int i = 0; i < razmer; i++)
{
cout<<"Zadaite "<<i+1<<" koordinatu: ";
cin>>x[i];
}
};
if(razmer==2)
{Q3 = Q3.function(x, E, method, it);}
else
{
Q3 = Q3.GZ_3(x, E, maxit, it, tochnost, method, razmer);
}
cout<<"Kolichestvo iteratsii: "<<it;
if (tochnost == 1)
{
cout<<"tochnost dostignuta... "<<endl;
}
else
{
cout<<"tochnost ne dostignuta "<<endl;
}
Q3.Write();
cout<<"Prodoljit rascheti? (y/n)"<<endl;
next = getch();
current++;
}
while (next != 'n');
}
Соседние файлы в папке р 1-5, 2 вар.; 7 лаб. метод Полака Рибьера + Лекции МО + перевод ГА