Спецификация программы
double d_left; //левый край интервала
double d_right; //правый край интервала
double func(double t); // заданая функция
double dfunc(double k); //производная
void antigradNapr(); //антиградиентное направление
void KOSHI(double e); //метод Коши
double getNorma(const CVector x); //норма
double Davidon(double e); //метод Давидона
double formules(double c); //формулы
void Swann4(double t); //метод Свенна 4
int funcNumber; //номер функции
double alfaPoint; //точка Альфа
int numberOfFormula; //номер формулы
int getSize() const; //получить размер
Текст программы
#include <stdio.h>
#include <conio.h>
#include "math.h"
#include <iostream.h>
//class vector(for math vector operations)
class CVector
{
public:
CVector(int VectorSize);
CVector( const CVector & );
~CVector(void);
int getSize() const;
double & operator[](int subscript);
const double &operator[](int subscript) const;
const CVector & operator=(const CVector &right);
bool operator==( const CVector &right) const;
bool operator!=( const CVector &right) const;
CVector operator*(const double k) const;
double operator*(const CVector &right) const;
CVector operator+(const double &alfaPoint) const;
CVector operator-(const double alfaPoint) const;
CVector operator+(const CVector &right) const;
CVector operator-(const CVector &right) const;
CVector operator-() const;
private:
double *vectorPointer;
intsize;
};
CVectorx0(2),result(2); //для хранения промежуточных и окончательного результата
CVector p(2),step(2);
int numberOfVariables;
double d_left,d_right;
//class storing all nessesary data for optimisation methods
class CMetOp
{
public:
CMetOp();
~CMetOp();
double func(double t);
double dfunc(double k);
void antigradNapr();
void KOSHI(double e);
double getNorma(const CVector x);
double Davidon(double e);
double formules(double c);
void Swann4(double t);
private: //переменные класса
int numberOfVariables;
int funcNumber;
int d;
double alfaPoint;
public:
int numberOfFormula;
};
//class vector methods describtion
CVector::CVector(int VectorSize)
{
size = VectorSize ;
vectorPointer = new double[size];
//for( int i = 0; i < size; i++ )
// vectorPointer[i]=0;
vectorPointer[0]=-1.2;
vectorPointer[1]=1;
}
CVector::CVector(const CVector &init) : size(init.size)
{
vectorPointer = new double[size];
for( int i = 0; i < size; i++ )
vectorPointer[i]=init.vectorPointer[i];
}
CVector::~CVector(void)
{
delete [] vectorPointer;
}
int CVector::getSize() const
{
return size;
}
double & CVector::operator[](int subscript)
{
return vectorPointer[subscript];
}
const double & CVector::operator[](int subscript) const
{
return vectorPointer[subscript];
}
const CVector & CVector::operator=(const CVector &right)
{
if(&right!=this)
{
if( size!= right.size)
{
delete [] vectorPointer;
size=right.size;
vectorPointer = new double[size];
}
for ( int i = 0; i < size; i++)
vectorPointer[i] = right.vectorPointer[i];
}
return *this;
}
bool CVector::operator==( const CVector &right) const
{
if( size != right.size )
return false;
for (int i = 0; i < size; i++)
if ( vectorPointer[i] != right.vectorPointer[i])
return false;
return true;
}
bool CVector::operator!=( const CVector &right) const
{
return ! (*this == right );
}
CVector CVector::operator*(const double k) const
{
CVector result(size);
for (int i=0; i<size;i++)
result[i]=k*vectorPointer[i];
return result;
}
CVector CVector::operator+(const double &alfaPoint) const
{
CVector result(size);
for (int i=0; i<size;i++)
result[i]=vectorPointer[i]+alfaPoint;
return result;
}
CVector CVector::operator-(const double alfaPoint) const
{
return *this+(-alfaPoint);
}
CVector CVector::operator+(const CVector &right) const
{
CVector result(size);
for (int i=0; i<size;i++)
result[i]=vectorPointer[i] + right[i];
return result;
}
double CVector::operator*(const CVector &right) const
{
double result=0;
for (int i=0; i<size;i++)
result+=vectorPointer[i]*right[i];
return result;
}
CVector CVector::operator-(const CVector &right) const
{
CVector result(size);
for (int i=0; i<size;i++)
result[i]=vectorPointer[i] - right[i];
return result;
}
CVector CVector::operator-() const
{
CVector result(size);
for (int i=0; i<size;i++)
result[i]=-vectorPointer[i];
return result;
}
CMetOp :: CMetOp()
{
}
CMetOp :: ~CMetOp()
{
}
double CMetOp :: func(double t)
{
CVector x2(2);
for(int k=0;k<2;k++)
x2[k]=x0[k]+t*p[k];
return (100*pow((x2[1]-x2[0]*x2[0]),2)+pow((1-x2[0]),2));
}
doubleCMetOp::dfunc(doublek) //Частные производные функции
{
switch(funcNumber) // в зависимости от номера функции
{
case1:
switch(numberOfVariables) // в зависимости от переменной, по которой дифференцируют
{
case 0:
return 2*((x0[0]+k*p[0])-(x0[1]+k*p[1]));
case 1:
return 4*(x0[1]+k*p[1])-2*(x0[0]+k*p[0])+1;
default:
return0;
}
case2:
switch(numberOfVariables) // в зависимости от переменной, по которой дифференцируют
{
case 0:
return 2*(x0[0]+k*p[0]-1);
case 1:
return 2*(x0[1]+k*p[1]-3);
case 2:
return 8*(x0[2]+k*p[2]+5);
default:
return0;
}
case3:
switch(numberOfVariables) // в зависимости от переменной, по которой дифференцируют
{
case 0:
return -400*((x0[1]+k*p[1])-(x0[0]+k*p[0])*(x0[0]+k*p[0]))-2*(1-(x0[0]+k*p[0]));
case 1:
return 200*((x0[1]+k*p[1])-(x0[0]+k*p[0])*(x0[0]+k*p[0]));
default:
return 0;
}
default:
return 0;
}
}
/**********************Antigradientnoe napravlenie***************************/
void CMetOp :: antigradNapr()
{
p[0]=400*(x0[1]-x0[0]*x0[0])*x0[0]+2*(1-x0[0]);
p[1]=-200*(x0[1]-x0[0]*x0[0]);
}
/****************************getNorma****************************************/
double CMetOp :: getNorma(const CVector x)
{
return(sqrt(pow((x[0]-x0[0]),2)+pow((x[1]-x0[1]),2)));
}
/***************************Ras4etnie formuli********************************/
double CMetOp :: formules(double c)
{
double z,w;
z=dfunc(d_left)+dfunc(d_right)+3*(func(d_left)-func(d_right))/d_right;
w=sqrt(z*z-dfunc(d_left)*dfunc(d_right));
c=d_left+((z-dfunc(d_left)+w)/(dfunc(d_right)-dfunc(d_left)+2*w))*(d_right-d_left);
return c;
}
void CMetOp :: Swann4(double t)
{
double s=0;
if(t>fabs((func(0)-dfunc(0))/dfunc(0)))
t=fabs((func(0)-dfunc(0))/dfunc(0));
if(dfunc(0)>0)
for(int k=0;k<2;k++)
p[k]=-p[k];
do
{
s=s+t;
t=2*t;
}
while((dfunc(0)*dfunc(s))>0);
d_left=s-t/2;
d_right=s;
}
/*****************************Metod Devidona*********************************/
double CMetOp :: Davidon(double e)
{
double c;
Swann4(1);
do
{
c=formules(c);
if(dfunc(c)<0)
d_left=c;
else
d_right=c;
}
while(fabs(dfunc(c))>e);
return c;
}
/******************************Metod Koshi***********************************/
void CMetOp :: KOSHI(double e)
{
double d_alfaPoint;
CVector x1(2);
int k;
int g=0;
for(k=0;k<2;k++)
x1[k]=x0[k];
do
{
g++;
for(k=0;k<2;k++)
x0[k]=x1[k];
antigradNapr();
d_alfaPoint=Davidon(e);
for(int k=0;k<2;k++)
x1[k]=x0[k]+d_alfaPoint*p[k];
}
while((getNorma(x1)>e)||(fabs(func(0)-func(d_alfaPoint))>e));
for(k=0;k<2;k++)
x0[k]=x1[k];
cout<<"\nKolli4estvo iteraciy: k = "<<g;
}
/******************************Main***********************************/
void main()
{
CMetOp method;
int funcNumber;
double E;
cout<<"\n---Laboratornaya rabota 5. Issledovanie gradientnih metodov.---";
cout<<"\n-------------------------Variant 1-----------------------------";
cout<<"\n------------------------Metod Koshi----------------------------\n";
do
{
cout<<"1 - x1^2 + 2*x2^2 - 2*x1*x2 + x2 \n";
cout<<"2 - (x1-1)^2+(x2-3)^2+4*(x3+5)^2 \n";
cout<<"3 - 100*(x2-x1^2)^2+(1-x1)^2\n";
cout<<"Enter number of function: ";
cin>>funcNumber;
}
while(funcNumber>3 && funcNumber<1);
cout<<"\nVvedite to4nost' poiska: E = ";
cin>>E;
cout<<"\nNa4al'naya to4ka poiska: Xo = ( -1.2 ; 1 )";
switch(funcNumber)
{
case 1:
numberOfVariables=2;
break;
case 2:
numberOfVariables=3;
break;
case 3:
numberOfVariables=2;
break;
default:
numberOfVariables=0;
break;
}
//method.InputPoint(numberOfVariables, funcNumber);
method.KOSHI(E);
cout<<"\nRezultat minimizacii: ";
cout<<"( "<<x0[0]<<" ; "<<x0[1]<<" )";
getch();
}