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

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

.cpp
Скачиваний:
3
Добавлен:
01.05.2014
Размер:
10.53 Кб
Скачать
#include <iostream.h>
#include <conio.h>
#include <math.h>

class Ourvector
{
	public:
		Ourvector(int Size);
		Ourvector(const Ourvector& v);
		~Ourvector();
		int size() const;
		double& Ourvector::operator[](int N);
		double Ourvector::operator[](int N) const;
		void Sum(const Ourvector& a, const Ourvector& b);
		void difference(const Ourvector& a, const Ourvector& b);
		Ourvector Ckal(Ourvector x, double d);
		double mult(const Ourvector& a, const Ourvector& b);
		Ourvector& operator=(const Ourvector& a);
		void  operator*=(double d);
		void Write() const;
		Ourvector gradi(const Ourvector& x);
		Ourvector Evec(int n, int Num);
		double Norma(Ourvector x);
		
		void Swenn(const Ourvector& x, Ourvector& p, double& ala, double& alb);
		double Zolotova1(Ourvector& x, Ourvector p, double al1, double al2, double E);
		double Powell(Ourvector& x, Ourvector p, double al1, double al2, double E);
		
		Ourvector avragenie(Ourvector& x, double E, int maxiter, int& iter, int& bool, int method);
		
		
		
		Ourvector operator+(const Ourvector& a)
		{
			Ourvector s(nSize);
			s.Sum(*this, a);
			return s;
		}
		Ourvector operator-(const Ourvector& a)
		{
			Ourvector s(nSize);
			s.difference(*this, a);
			return s;
		}
		double operator*(const Ourvector& a)
		{
			double w;
			Ourvector s(nSize);
			w = s.mult(*this, a);
			return w;
		}

	private:
		double* Coord;
		int nSize;
};
 void Ourvector:: operator*=(double d)
		{ for (int i = 0; i < nSize; i++)
			Coord[i] *= d;
		}

Ourvector::Ourvector(int Size)
{
	nSize = Size;
	Coord = new double[Size];
}
Ourvector::Ourvector(const Ourvector& v)
{
	nSize = v.size();
	Coord = new double[nSize];
	for (int i = 0; i < nSize; i++)
		Coord[i] = v[i];
}
Ourvector::~Ourvector()
{
	delete[] Coord;
}
int Ourvector::size() const
{
	return nSize;
}
double& Ourvector::operator[](int N)
{
	return *&Coord[N];
}
double Ourvector::operator[](int N) const
{
	return Coord[N];
}
Ourvector Ourvector::Ckal(Ourvector x, double d)
{   int i = x.size();
   Ourvector W(i);
   for(int j=0; j<i; j++)
     W[j] = x[j]*d;
   return W;
}
void Ourvector::Sum(const Ourvector& a, const Ourvector& 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 Ourvector::difference(const Ourvector& a,  const Ourvector& 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 Ourvector::mult(const Ourvector& a, const Ourvector& 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;
}
Ourvector& Ourvector::operator =(const Ourvector& a)
{
	for (int i = 0; i < nSize; i++)
	{
	 Coord[i] = a.Coord[i];
	}
	return *this;
}
void Ourvector::Write() const
{
	cout<<"The resulting vector is:"<<endl;
	for (int i = 0; i < nSize; i++)
	{
		cout<<Coord[i]<<endl;
	};
}
//*********************************************************************
//***********************************************************
double F (Ourvector 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 = pow(t[0]-1,2)+pow(t[1]-3,2)+4*pow(t[2]+5,2);

  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 ChP(Ourvector x, int i)
{
	int t = x.size();
	double w = -1000;
	double h = 0.000001;
	Ourvector q(t);
	if (t >= i)
	  w = ( F(x + q.Ckal(q.Evec(t, i), h)) - F(x - q.Ckal(q.Evec(t, i), h)) )/(2*h);
	return w;
}


Ourvector Ourvector::gradi(const Ourvector& x)
{
  int i = x.size();
  Ourvector w(i);
  for (int j = 1; j<=i; j++)
  {
    w[j-1] = ChP(x, j);
  }
  return w;
}

Ourvector Ourvector::Evec(int n, int Num)       // - koordinatniy ort
{                                         // dlinoy 'n'
  Ourvector W(n);                            // i 1-tsey na 'Num'
  int i=0;
  while (i<n)
  {
    W[i] = 0;
    i++;
  }
  W[Num-1] = 1;
    return W;
}

double Ourvector::Norma(Ourvector x)
{
  int i = x.size();
  double d=0;
  for (int j = 0; j < i; j++)
    d = d + x[j]*x[j];
  return sqrt(d);
}

void Ourvector::Swenn(const Ourvector& x, Ourvector& p, double& ala, double& alb)
{
  int r = x.size();
  Ourvector G(r);
  G = G.gradi(x);    //   Proverka napravlenia ubivania functsii...
  if ((G * p) > 0)   //
   {                 //
     p*=-1;
   }                 //
  double f1, f2, al = 0.000001;
  Ourvector x1(r);
  Ourvector x2(r);
  x1 = x;
  f1 = G * p;
  do
  {
    al = al*2;
    G = G.Ckal(p, al);
    x2 = x1 + G;
    G = G.gradi(x2);
    f2 = G * p;
  }
  while (f1*f2 > 0);
  alb = al;
  ala = al/2;
}


double Ourvector::Zolotova1(Ourvector& x, Ourvector p, double al1, double al2, double E)
{
  double l, m, f1, f2;
  int j=0;
  l = al1 + 0.38196601125*fabs(al1-al2);
  m = al1 + 0.61803398875*fabs(al1-al2);
  int r = x.size();
  Ourvector G(r);
  Ourvector x1(r);
  Ourvector x2(r);
  while (  (fabs(al1-al2) >= E) || (fabs(f1-f2) >= E)  )
  {
	  j = j + 1;
	  x1 = x + G.Ckal(p, l);
	  f1 = F(x1);
	  x2 = x + G.Ckal(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;
}


double Ourvector::Powell(Ourvector& x, Ourvector p, double al1, double al2, double E)
{
  double a, b, bb, c, d, dd, help1, help2;
  int r = x.size();
  Ourvector xa(r);
  Ourvector xb(r);
  Ourvector xc(r);
  Ourvector xd(r);

  a = al1;
  b = (al1+al2)/2;
  c = al2;
  xa = x + xa.Ckal(p, a);
  xb = x + xb.Ckal(p, b);
  xc = x + xc.Ckal(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.Ckal(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.Ckal(p, a);
    xb = x + xb.Ckal(p, b);
    xc = x + xc.Ckal(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.Ckal(p, d);
    bb = b;
    dd = d;
  }
  b = bb;
  d = dd;
  return (b + d)/2;
}

Ourvector Ourvector::avragenie(Ourvector& x, double E, int maxiter, int& iter, int& bool, int method)
    {

    double min,help,help2, al1=0, al2=0;
	int r=x.size(), k=1;
	Ourvector d(r), x1(r), x1t(r), x2(r), x2t(r), p(r), x3(r), g(r);

	x1=x;

	while(1)
	{
		x1t[0]=x1[0]+0.001;
		for(int j=1;j<r;j++) x1t[j]=x1[j];

		g=g.gradi(x1);
		p=g.Ckal(g,-1);
        
		Swenn(x1, p, al1, al2);
		if (method==1) min=Zolotova1(x1, p, al1, al2, E);
		if (method==2) min=Powell(x1, p, al1, al2, E);
		x2=x1+x1.Ckal(p,min);

		Swenn(x1t, p, al1, al2);
		if (method==1) min=Zolotova1(x1t, p, al1, al2, E);
		if (method==2) min=Powell(x1t, p, al1, al2, E);
		x2t=x1t+x1t.Ckal(p,min);

		d=x2-x2t;

		Swenn(x2, d, al1, al2);
		if (method==1) min=Zolotova1(x2, d, al1, al2, E);
		if (method==2) min=Powell(x2, d, al1, al2, E);
		x3=x2+x2.Ckal(d,min);

		if ((  Norma(g.gradi(x3)) < E  ) && (  k > maxiter  )) return x3;
		x1=x3;
		k++;
	}       
 }


/***********************************************/
void main()
{
  

  double E;
  int it=0, maxit, tochnost;
  int choice, razmer, method, itogoiter=0;
  char ans, dalshe;

  cout<<"////////////******************////////////////"<<endl;
  cout<<"This program uses Ovrageni method to find min of the chosen function."<<endl;
  cout<<"\n";
  cout<<"Selected methods for calculations are (Zolotova-1, Powell)"<<endl;
  cout<<endl;
  cout<<"Select function:"<<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) = 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;

  Ourvector x(razmer);
  for (int i = 0; i < razmer; i++)
    x[i] = 0;

  cout<<"By default starting point has coordinate x[i]=0.5. Change'? (y/n)"<<endl;
  ans = getch();
  if (ans == 'y')
      for (int i = 0; i < razmer; i++)
	{
	  cout<<"Gives "<<i+1<<" as coordinate:   ";
	  cin>>x[i];
	}

  Ourvector Q3(razmer);
  int help = 0;
  do
  {
  cout<<endl;
  cout<<"Select metod for calculation:"<<endl;
  cout<<"1. Metod Zolotovo (1);"<<endl;
  cout<<"2. Metod Powell"<<endl;
  cin>>method;

  cout<<"Enter max number iteratsii: ";
  cin>> maxit;
  cout<<"Enter pogreshnost' (E = 0.00001 - 0.0000000001) : ";
  cin>>E;
  cout<<endl;
  if (help > 0)
  {
    x = Q3;
    cout<<"Change starting point? (y/n)"<<endl;
    ans = getch();
    if (ans == 'y')
      for (int i = 0; i < razmer; i++)
	{
	  cout<<"Gives "<<i+1<<" as coordinate:   ";
	  cin>>x[i];
	}
  };

  Q3 = Q3.avragenie(x, E, maxit, it, tochnost, method);
 
  cout<<"Number of iteratsii so far:  "<<it;
  itogoiter = itogoiter + it;
  cout<<",  Total: "<<itogoiter<<endl;

  if (tochnost == 1)
    {
      cout<<"tochnost' accomplished... "<<endl;
    }
  else
    {
      cout<<"tochnost' not accomplished... "<<endl;
    }
      Q3.Write();
      cout<<"Continue calculations? (y/n)"<<endl;
      dalshe = getch();

     help++;
  }
  while (dalshe != 'n');
}