Discrete Coefficient values in objective function as a function of continuous decision variables
AnsweredHi,
I want to minimize the objective function given below.
The problem is the coefficient B is actually a function of C_rate. C_rate is a positive continuous decision variable. Ah = C_rate * delta_t . R,T and delta_t are constants.
(I can take log on both sides to make it solvable by gurobi)
The corresponding values for C_rates in the ranges (0C to 0.5C, 0.5C to 2C, 2C to 6C and 6C to 10C) is given below. So during optimization is it possible for gurobi to select every B value and then try the corresponding range of C_rate values and arrive at the optimal C_rate value?
Thank you.
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
Hi Jose,
As you mentioned, the best approach is to minimize \(\ln(Q_{\mathrm{loss}})\). We have:
\[\ln(Q_{\mathrm{loss}}) = y + \frac{-31700 + 370.3 \times \mathrm{C\_Rate}}{RT} + 0.55 z\] where \(z=\ln(A_h) = \ln(\mathrm{C\_Rate} \times \delta_t)\) and \(y\) is given below:
\[y = \begin{cases} \ln(31630) & 0 < \mathrm{C\_Rate} \leq \frac{C}{2} & \notag \\ \ln(21681) & \frac{C}{2} < \mathrm{C\_Rate} \leq 2C & \notag \\ \ln(12934) & 2C < \mathrm{C\_Rate} \leq 6C & \notag \\ \ln(15512) & 6C < \mathrm{C\_Rate} \leq 10C \end{cases}\]
You mentioned that \(R\), \(T\), \(\delta_t\) are constant. I assume \(C\) is also a constant.
The Model.addGenConstrPWL() and the Model.addGenConstrLog() methods can be used to model the variables \(y\) and \(z\), respectively. A possible implementation is given below (using arbitrary values for the constants). The \(y\) variable is a step-function of the variable \(\mathrm{C\_Rate}\) (see Piecewise-Linear Objectives on how to model jumps in a function.)
import gurobipy as gp
from gurobipy import GRB
from math import log
if __name__ == "__main__":
R, T, delta_t, C = 1, 1, 0.1, 1
model = gp.Model("")
c_rate = model.addVar(name="c_rate")
y = model.addVar(name="y")
z = model.addVar(lb=-GRB.INFINITY, name="z")
u = model.addVar(name="u)
# Minimize ln(Q_loss)
model.setObjective(y + (-31700 + 370.3 * c_rate) / (R * T) + 0.55 * z, sense=GRB.MINIMIZE)
# u = delta_t * c_rate
model.addConstr(u == delta_t * c_rate)
# z = ln(u) = ln(delta_t * c_rate)
model.addGenConstrLog(u, z)
# y = ln(31630) if 0 <= c_rate <= c/2;
# ln(21681) if c/2 <= c_rate <= 2c;
# ln(12934) if 2c <= c_rate <= 6c;
# ln(15512) if 6c <= c_rate <= 10c;
model.addGenConstrPWL(
c_rate,
y,
[0, C / 2, C / 2, 2 * C, 2 * C, 6 * C, 6 * C, 10 * C],
[
log(31630),
log(31630),
log(21681),
log(21681),
log(12934),
log(12934),
log(15512),
log(15512),
],
)
model.optimize()
for var in model.getVars():
print(f"{var.VarName}: {var.X}")Best regards,
Maliheh
0 -
Thank you Maliheh. It works. :)
0
Post is closed for comments.
Comments
3 comments