Skip to main content

Discrete Coefficient values in objective function as a function of continuous decision variables

Answered

Comments

3 comments

  • Official comment
    Simranjit Kaur
    • Gurobi Staff Gurobi Staff
    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?.
  • Maliheh Aramon
    • Gurobi Staff Gurobi Staff

    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
  • Jose peeterson
    • Gurobi-versary
    • Conversationalist
    • Curious

    Thank you Maliheh. It works. :)

    0

Post is closed for comments.