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

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

((x [t] - x [t-1]) / шаг) ^ 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.

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

L.


person L. Burg    schedule 04.09.2018    source источник
comment
Да, вы можете добавить к цели квадратичные члены. См. Пример QPex1.java, поставляемый с CPLEX. Это то, о чем вы спрашивали? Вы должны просто попробовать его, чтобы увидеть, дает ли он желаемый эффект сглаживания. Другой вариант - попробовать использовать пул решений, чтобы найти альтернативные оптимальные решения.   -  person rkersh    schedule 04.09.2018
comment
Спасибо за Ваш ответ. Решением проблемы было переписать (x2-x1) ^ 2 как x2x2 - 2x2x1 + x1x1. Но подсказка для QPex1.java также была очень полезной.   -  person L. Burg    schedule 12.09.2018
comment
Рад помочь. Кстати, если вы хотите заработать несколько очков репутации, не стесняйтесь предоставить более подробный ответ на этот вопрос. (это совершенно законно и рекомендуется отвечать и принимать свои собственные ответы).   -  person rkersh    schedule 13.09.2018


Ответы (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. изменение с течением времени оставалось небольшим.

person L. Burg    schedule 13.09.2018