Я разрабатываю инструмент оптимизации для домашней энергосистемы, которая также содержит аккумулятор. Все значения верны, и решение имеет смысл. Проблема в том, что раствор содержит очень сильные колебания. Это означает, что переменная решения часто равна 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.
С наилучшими пожеланиями,
Л.
Спасибо за Ваш ответ. Решением проблемы было переписать (x2-x1) ^ 2 как x2x2 - 2x2x1 + x1x1. Но подсказка для QPex1.java также была очень полезной.
Рад помочь. Кстати, если вы хотите заработать несколько очков репутации, не стесняйтесь предоставить более подробный отвечать на этот вопрос (это совершенно законно и рекомендуется отвечать и «принимать» свои собственные ответы).
Проблема решилась следующим образом:
Кажется, невозможно добавить выражение типа 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. изменение с течением времени оставалось небольшим.
Да, вы можете добавить к цели квадратичные члены. См. Пример
QPex1.java
, поставляемый с CPLEX. Это то, о чем вы спрашивали? Вы должны просто попробовать его, чтобы увидеть, дает ли он желаемый эффект сглаживания. Другая идея - попробовать использовать пул решений для проверки альтернативных оптимальных решений.