Скачиваний:
4
Добавлен:
01.05.2014
Размер:
80.38 Кб
Скачать

Задание

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

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

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

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

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

В программе пользователю предоставляется возможность выбрать тестовую функцию по своему усмотрению.

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

#include <iostream.h>

#include <math.h>

class vector

{

private:

int num, fun, d;

double x[5], p[5], step, l;

public:

vector();

void InputDot(int n, int fun1, int def);

void PassInfo();

double Function(double k);

double Differential(int n, double k);

void Gradient(int n);

double CreateStep();

void OutResult();

};

vector::vector() // "Пустой" вектор

{

for (int i=0; i<5; i++)

{

x[i]=0;

p[i]=0;

}

step=0; // Шаг

l=0; // Длина

fun=0; // Функция для работы еще не выбрана

}

void vector::InputDot(int n, int fun1, int def) // Задаем начальную точку

{

cout<<"Enter coordinates of an index point\n";

for (int i=0; i<n; i++)

{

cout<<"x["<<i<<"] :";

cin>>x[i];

}

num=n;// Запоминаем с каким количеством переменных работаем

fun=fun1; // Фиксируем номер выбранной функции

d=def; // Выбранный тип дифференцирования

}

void vector::PassInfo() //Новая координата вектора, образованная путем смещения

{

for (int i=0; i<num; i++) // Уже знаем кол-во переменных

{

x[i]=x[i]+step*p[i]; // Уже знаем значение step

}

}

double vector::Function(double k) // Меню выбора тестовой функции

{

switch(fun)

{

case 1:

return (x[0]+k*p[0])*(x[0]+k*p[0])+2*(x[1]+k*p[1])*(x[1]+k*p[1])-2*(x[0]+k*p[0])*(x[1]+k*p[1])+(x[1]+k*p[1]);

break;

case 2:

return (x[0]+k*p[0]-1)*(x[0]+k*p[0]-1)+(x[1]+k*p[1]-3)*(x[1]+k*p[1]-3)+4*(x[2]+k*p[2]+5)*(x[2]+k*p[2]+5);

break;

case 3:

return 100*((x[1]+k*p[1])-(x[0]+k*p[0])*(x[0]+k*p[0]))*((x[1]+k*p[1])-(x[0]+k*p[0])*(x[0]+k*p[0]))+(1-(x[0]+k*p[0]))*(1-(x[0]+k*p[0]));

break;

default:

return 0;

}

}

double vector::Differential(int n, double k) //Частные производные функции

{

double x1, h=0.0000001, d1, d2; // Потребуется для численного дифференцирования

if(d==1) // Аналитический тип дифференцирования

{

switch(fun) // в зависимости от номера функции

{

case 1:

switch(n) // в зависимости от переменной, по которой дифференцируют

{

case 0:

return 2*((x[0]+k*p[0])-(x[1]+k*p[1]));

case 1:

return 4*(x[1]+k*p[1])-2*(x[0]+k*p[0])+1;

default:

return 0;

}

case 2:

switch(n) // в зависимости от переменной, по которой дифференцируют

{

case 0:

return 2*(x[0]+k*p[0]-1);

case 1:

return 2*(x[1]+k*p[1]-3);

case 2:

return 8*(x[2]+k*p[2]+5);

default:

return 0;

}

case 3:

switch(n) // в зависимости от переменной, по которой дифференцируют

{

case 0:

return -400*((x[1]+k*p[1])-(x[0]+k*p[0])*(x[0]+k*p[0]))-2*(1-(x[0]+k*p[0]));

case 1:

return 200*((x[1]+k*p[1])-(x[0]+k*p[0])*(x[0]+k*p[0]));

default:

return 0;

}

default:

return 0;

}

}

else // Численное дифференцирование

{

x1=x[n]; // Переменную, по которой дифференцируем, обзываем x1

x[n]=x[n]-h;

d1=Function(0);

x[n]=x[n]+2*h;

d2=Function(0);

x[n]=x1;

return (d1+d2)/2*h;

}

}

void vector::Gradient(int n) //Градиент - вектор из частных производных

{

for(int i=0; i<num; i++)

{

if(i==n)

p[i]=Differential(i,0);

else

p[i]=0;

}

}

double vector::CreateStep() // Получим step - результат одномерной минимизации

{

double h1,x_1,x_2,a,b,n,e;

int k=0;

h1=0.01;

x_1=h1;

if(Function(0)<Function(x_1)) // Метод Свенна

{

h1=-h1;

x_1=h1;

}

do

{

h1=2*h1;

x_1=x_1+h1;

}

while(Function(x_1-h1)>Function(x_1));

a=x_1-1.5*h1; // Получили отрезок

b=x_1;

if(a>b) // Для удобства переименовали границы

{

n=a;

a=b;

b=n;

}

e=0.001;

x_1=a+0.618*fabs(b-a); // Локализуем минимум методом Золотого Сечения 2

do

{

x_2=a+b-x_1;

if((x_1<x_2)&&(Function(x_1)<Function(x_2)))

b=x_2;

if((x_1<x_2)&&(Function(x_1)>=Function(x_2)))

{

a=x_1;

x_1=x_2;

}

if((x_1>x_2)&&(Function(x_1)<Function(x_2)))

a=x_2;

if((x_1>x_2)&&(Function(x_1)>=Function(x_2)))

{

b=x_1;

x_1=x_2;

}

k++;

}

while((fabs(b-a)>e)&&(k<200));

step=(a+b)/2; // Найденый минимум

return step;

}

void vector::OutResult() // Вывод результата на экран

{

cout<<"The following coordinates of a point of a minimum are received:\n";

for(int i=0;i<num;i++)

{

cout<<x[i]<<" ";

}

cout<<'\n';

}

void main()

{

vector X;

double e, s;

int k=0, M, i, number, flag=1, fun1, def;

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

switch(fun1)

{

case 1:

number=2;

break;

case 2:

number=3;

break;

case 3:

number=2;

break;

default:

number=0;

break;

}

cout<<"Enter accuracy for criterion of the ending of search: e=";

cin>>e;

cout<<"Set restrictions on amount of iterations: M=";

cin>>M;

cout<<"Enter type of differentiation:\n";

cout<<"1 - Analytical\n";

cout<<"2 - Numerical\n";

cin>>def;

X.InputDot(number, fun1, def);

do

{

for(i=0; i<number; i++)

{

X.Gradient(i);

s=X.CreateStep();

X.PassInfo();

}

k++;

}

while((fabs(X.Function(0)-X.Function(-s))>=e)&&(k<M)); //Главным образом, здесь е влияет на результат

cout<<"Quantity of the executed steps: "<<k<<'\n';

X.OutResult();

}

Соседние файлы в папке Лабораторная работа №5