Не могу правильно подобрать структуру классов и методов для решения задачи оптимизации именно в стиле ООП.
Дано: функция с ограничениями (равенства и неравенства) для примера возьмем простую нелинейную функцию с ограничением равенством
x^2 + y^2 -> min
x + y = 1
Метод решения: метод штрафных функций для преобразования функции и ограничения в единую функцию, оптимизация может производиться любым методом безусловной оптимизации, я например разбираю градиентный спуск.
Как я решал:
main
создавал объекты двух классов и массив double *point
с начальными значениями точки, объект problem
и gradient_descent
. После чего, problem
и point
передавал в инициализатор gradient_descent
и запускал метод optimize
.
getF
и getG
изменились добавился "коэффициент резкого возрастания функции" gamma
, а оптимизация попала в цикл с изменяющимся параметром gamma
.
Problem
со всеми свойственными ему атрибутами и методами и парой переопределяемых методов, например virtual bool solve()
и от него унаследовать класс например GradientDescent:Problem
дабы просто использовать методы и атрибуты класса родителя и не передавать какието объекты и параметры.
Однако я не могу никак придумать "связку" наследования Задача -> Метод штрафных функций -> Любой метод безусловной оптимизации
.
Может ли кто нибудь "на пальцах" объяснить возможна ли такая связка?
Пока что в голову приходит только что в методе класса PenaltyM
будет крутиться цикл с GradientDescent:Problem
. UPD По хорошему это ведь может касаться не только моей конкретной задачи. А задач на подобии:
|----------------> Method_1
|------>Method_0-----^
Problem |----------------> Method_2
|----------------> Method_3
|------>Method_4-----^
Т.е. по идее должен быть какой-то обобщенный класс метод, который может наследоваться от проблемы напрямую или иметь промежуточный метод. К сожалению я мыслю в формате процедурном, может быть кто нибудь сталкивался с подобным и сможет направить? Методы 1,2 и 3 должны как-то узнать, что их функцию оптимизации запускают либо просто так либо еще и через методы 0 или 4.
UPD 2 Я нашел один из подходов который решает мою задачу, но он не универсален. Как сделать так чтобы PenaltyMethod стал универсальным - я пока что не могу адекватно представить и реализовать. Ну а по делу, код выглядит так:
class Problem{
public:
Problem(){}
Problem (int size,
double *point,
double *constr_non_eq,
bool **constr_eq):size_(size),
point_(point),
constrains_non_eq_(constr_non_eq),
constrains_eq_(constr_eq){}
virtual ~Problem(){}
virtual double *getResult() = 0;
virtual bool solve() = 0;
protected:
virtual double getFunctionVal(){}
long size_;
double *point_;
double *constrains_non_eq_;
bool **constrains_eq_;
};
class GradDesc : Problem{
public:
GradDesc():Problem(){}
GradDesc(int size,
double *point,
double *constr_non_eq,
bool **constr_eq,
double min_step_lenght,
double min_eps,
double min_iter): min_step_lenght_(min_step_lenght),
min_eps_(min_eps),
min_iter_(min_iter),
Problem(size, point, constr_non_eq, constr_eq){}
virtual bool getGradientVal(){}
bool solve() override {
optimize();
}
double *getResult() override{}
bool optimize() {
// optimization, will use private methods
// getNewPoint and getGradientNorm
}
protected:
bool getNewPoint(){}
double getGradientNorm(){}
double *grad_;
double min_step_lenght_;
double min_eps_;
int min_iter_;
};
class PenaltyMethod : GradDesc{
public:
PenaltyMethod():GradDesc(){}
PenaltyMethod(int size,
double *point,
double *constr_non_eq,
bool **constr_eq,
double min_step_lenght,
double min_eps,
double min_iter,
int gamma_start,
double mult,
double accuracy):gamma_(gamma_start),
mult_(mult),
accuracy_(accuracy),
GradDesc(size, point, constr_non_eq, constr_eq,min_step_lenght,min_eps,min_iter){}
bool solve() override {
for (int i = 0; i < 5 ; ++i) {
optimize();
}
}
double *getResult() override{}
protected:
double getFunctionVal() override{}
bool getGradientVal() override{}
private:
int gamma_;
double mult_;
double accuracy_;
};
int main() {
int size = 3;
double *point = new double[size];
double *constr_non_eq = new double[15];
bool ** constr_eq = new bool*[size];
for (int i = 0; i < size ; ++i) {
constr_eq[i] = new bool[9];
}
PenaltyMethod *pm = new PenaltyMethod(size,point,constr_non_eq, constr_eq,1e-5,1e-5,50,1,10,1e-10);
pm->solve();
pm->getResult();
return 0;
}
Напрягает нагромождение инициализации конструкторов и то что если у меня вдруг поменяется промежуточный метод оптимизации. То придется еще и от него наследовать метод Штрафных функций. В голове крутятся мысли по обобщению методов, но учитывая отсутствие опыта в С++ и незнакомство с шаблонами пока что приходится пользоваться такими вот костылями.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Разбираюсь с QDockWidgetСтолкнулся с непонятной для меня вещью - под MS Windows заголовок окошка в доке отображается всегда одинаково, вне зависимости...
Нужно отсортировать слова, например: ёжик, Азбука, аромат, ЁжПроблема в том, что буква ё не сортируется