Скачиваний:
7
Добавлен:
03.06.2014
Размер:
7.94 Кб
Скачать
#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;// перегрузка оператора для работы с типом данных double
		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);// перегрузка оператора для присваивания вектору значении другого вектора
		void print() const;//Вывод значении массива
		Vector Grad(const Vector& x);// Градиент
		/**Лабораторная №3**/
		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);// Золотое сечение 1 для векторных переменных 
		double Powell(Vector& x, Vector p, double al1, double al2, double E);// Метод Пауэлла для векторных переменных

		Vector Orta(int n, int Num);// Единичная орта
	
		Vector function(Vector& x, double E, int method);// Метод золотого сечения

		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::print() const
{
	cout<<"This is vector:"<<endl;
	for (int i = 0; i < nSize; i++)
	{
		cout<<Coord[i]<<endl;
	};
}


double F (Vector t)
{
  double result = 0;

    result =t[0]*t[0]+3*t[1]*t[1]+2*t[0]*t[1];
 
  return result;
}


double Differ(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.Orta(t, i), h)) - F(x - q.Scal(q.Orta(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] = Differ(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);
  alb = al;
  ala = al/2;

}
double Vector::ZS1(Vector & x, Vector 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();
  Vector G(r);
  Vector x1(r);
  Vector x2(r);
  while (  (fabs(al1-al2) >= E)   )
  {
	  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::Orta(int n, int Num)       // координатная орта длиной n с 1 на диагонали 1
{                                         // 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::Powell(Vector & x, Vector p, double al1, double al2, double E)
{E=0.01;
  double a, b,  c, d,  help1, help2;
  int r = x.size();
  Vector xa(r);
  Vector xb(r);
  Vector xc(r);
  Vector xd(r);
  int sch=0;
  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.000000000001;
  d = 0.5*help1/help2;
  xd = x + xd.Scal(p, d);

  while ( fabs((d-b)/b) >= E   )
  {
	  sch++;
    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::function(Vector& x, double E, int method)
{
  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); //alpha i-oe
	    if (method == 2)
	      al = G.Powell(t, p, a, b, E); //alpha i-oe
	    t = t + G.Scal(p, al);
	 

  
  return t;
}

void main()
{


  double E;
  E=0.000001;

  int method;


  cout<<"Laboratornaya_3"<<endl;
  cout<<"f(x1,x2) = x1^2 + 3x2^2 + 2x1*x2;"<<endl;
  Vector x(2);
  Vector Q3(2);
    Vector Q4(2);
cout<<"Metod Zolotogo Sechenia-1 and Method Pauella"<<endl;
x[0]=1;
x[1]=1;
Q3 = Q3.function(x, E, 1);
cout<<"Method Zolotogo Sechenia-1 "<<endl;


Q3.print();
x[0]=1;
x[1]=1;
Q4 = Q4.function(x, E, 2);
cout<<"Method Pauella "<<endl;
Q4.print();
getch();
}
Соседние файлы в папке р 1-5, 2 вар.; 7 лаб. метод Полака Рибьера + Лекции МО + перевод ГА