Добавить квадратичный штрафной член к целевой функции в cplex (Java)

Я разрабатываю инструмент оптимизации для домашней энергосистемы, которая также содержит аккумулятор. Все значения верны, и решение имеет смысл. Проблема в том, что раствор содержит очень сильные колебания. Это означает, что переменная решения часто равна 0 или максимальному значению. Чтобы избежать этого, я хотел бы добавить квадратичное ограничение, которое штрафует разницу двух значений (что-то вроде производной). Должно выглядеть примерно так:

((x[t] - x[t-1]) / stepsize) ^ 2

Где x - интересующая переменная решения. Например. power_g_h[t].

Моя целевая функция (пока) определяется следующим образом:

IloLQNumExpr expr = model.lqNumExpr();

        for (int t = 0; t < timesteps; t++) {
            expr.addTerm(problem.getCosts().getElectricityCosts(t), power_g_h[t]);
            expr.addTerm(problem.getCosts().getElectricityCosts(t), power_g_b[t]);
            expr.addTerm(problem.getCosts().getElectricityCosts(t), power_g_bev[t]);
            expr.addTerm(problem.getCosts().getFeedCompensation(), power_pv_g[t]);

        } 

Я надеюсь, что это было в некоторой степени понятно, и кто-нибудь сможет сказать, возможно ли это вообще в CPLEX.

Если это невозможно, я был бы очень рад подсказкам, как «сгладить» решение в CPLEX.

С наилучшими пожеланиями,

Л.

Да, вы можете добавить к цели квадратичные члены. См. Пример QPex1.java, поставляемый с CPLEX. Это то, о чем вы спрашивали? Вы должны просто попробовать его, чтобы увидеть, дает ли он желаемый эффект сглаживания. Другая идея - попробовать использовать пул решений для проверки альтернативных оптимальных решений.

rkersh 04.09.2018 20:13

Спасибо за Ваш ответ. Решением проблемы было переписать (x2-x1) ^ 2 как x2x2 - 2x2x1 + x1x1. Но подсказка для QPex1.java также была очень полезной.

L. Burg 12.09.2018 11:48

Рад помочь. Кстати, если вы хотите заработать несколько очков репутации, не стесняйтесь предоставить более подробный отвечать на этот вопрос (это совершенно законно и рекомендуется отвечать и «принимать» свои собственные ответы).

rkersh 13.09.2018 01:23
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
199
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема решилась следующим образом:

Кажется, невозможно добавить выражение типа x * ((a - b) ^ 2). Вместо этого было решено записать вышеупомянутое как x*a*a - 2x*a*b + x*b*b. Где x - штрафной коэффициент, а a и b - переменные решения. Таким образом можно было добавить член к целевой функции в cplex. В коде это выглядит примерно так:

IloCplex model = new IloCplex();
...
IloLQNumExpr expr = model.lqNumExpr();

expr.addTerm(x, a, a);
expr.addTerm(x, b, b);
expr.addTerm(-2 * x, a, b);

В моем случае a и b были одной и той же переменной для двух последовательных временных шагов, s.t. изменение с течением времени оставалось небольшим.

Другие вопросы по теме