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

Министерство Образования Российской Федерации

Санкт-петербургский государственный ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ «ЛЭТИ» ИМЕНИ В. И.УЛЬЯНОВА (ЛЕНИНА)

197376, Санкт-Петербург, ул. Проф. Попова, 5

Факультет компьютерных технологий и информатики

Кафедра САПР

«ЗАЧТЕНО»

________ П.А. Алешкевич

ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ №5

Проектирование программы оптимизации

Студенты группы 2375 А. Филатов

В. Каверзин

Санкт Петербург 2004

Содержание:

Задание 3

Спецификация программы 3

Текст программы 3

Описание интерфейса 10

Сравнение с работой надстройки «Поиск решения» 12

Результаты тестирования программы 12

Ответы на контрольные вопросы 13

 Наследование относится только к классам объектов. Это означает, что каждый объект может иметь наследников, каждый из которых будет обладать всеми полями и методами своего предка. Кроме того, как правило, классы-наследники совместимы по типу со своими предками. Наследование бывает двух видов: 13

Вывод 14

Задание

Целью работы является изучение современной технологии разработки программ оптимизации, ориентированных на язык C++.

Реализовать на языке С++ программу оптимизации. Протестировать программу и сравнить результаты работы заданных методов оптимизации при использовании различных критериев окончания поиска и при задании различных значений погрешности локализации минимума. Сделать выводы.

Спецификация программы

Программа построена таким образом, чтобы пользователь имел возможность оказывать определяющее воздействие на ход выполнения программы и алгоритмы поиска решений. Для этого в основной функции GZ_3, решающей задачу нахождения минимума выбранной функции методом Гаусса-Зейделя, реализована возможность определения максимального количества итераций, определения интересующей точности вычислений. В программе предусмотрена возможность повторного запуска процесса вычисления с корректирующими значениями начальной точки, максимального количества итераций и интересующей точности.

Основным объектом, которым пользуются все функции программы, является объект «Вектор», который представлен в программе классом Vector. В классе реализованы все процедуры обработки объектов классаVector, необходимые для работы программы. Основная расчетная функцияGZ_3 возвращает именно объект классаVector.

В программе пользователю предоставляется возможность выбрать метод нахождения шага, доставляющего минимум целевой функции при движении вдоль заданной прямой. Таких методов в программе реализовано два: метод Золотого Сечения(1) и метод Пауэлла. Они оба имеют одинаковые параметры, и их задача сводится только к нахождению шага, доставляющего минимум целевой функции при движении вдоль заданной прямой.

Текст программы

#include <iostream.h>

#include <conio.h>

#include <math.h>

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);

/***************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);

double Pauell(Vector& x, Vector p, double al1, double al2, double E);

/***************Lab4***************/

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);

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;

}

double operator*(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;

}

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;

};

}

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);

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(Vector x, int i) //formula dlia chislennogo differentsirovania

{

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;

}

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;

}

void Vector::Swenn(const Vector& x, Vector& p, double& ala, double& alb)

{

int r = x.size();

Vector G(r);

G = G.Grad(x); // Proverka napravlenia ubivania functsii...

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)

{ // metod Zolotogo Sechenia-1

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) )

{

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::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::Pauell(Vector& x, Vector p, double al1, double al2, double E)

{ //metod Pauella

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');

}

Соседние файлы в папке LABA5