Skip to main content

Three conditions in the objective function

Answered

Comments

3 comments

  • Shaojie Liu
    • Gurobi-versary
    • Conversationalist
    • First Question

    I noticed three are several posts discussing how to model conditional constraints with Gurobi. But there currently is not a particular example or demonstration how to model three conditions (and even nested conditions). I hope this post can accomodate such insufficiency. 

    0
  • Lennart Lahrs
    • Gurobi Staff

    Hi Shaojie,

    You can express this type of objective using auxiliary variables. Please find below some comments and a code example that I hope will help you with your problem.

    • Gurobi can handle bilinear terms, so for each multiplication of more than two variables, we need to define auxiliary variables until we are left with only bilinear terms; here they are called a_squared, term_1, and term_2.
    • To activate and deactivate terms of the objective function, we need conditional variables; here, they are called p_positive and a_positive.
    • Because the third case of your objective function depends on two conditions, I added another auxiliary variable (p_and_a_positive) which is positive if both a and p are positive, using a general constraint
    M = 1e6 # Big M
    E = 1e-6 # Epsilon

    p_positive = model.addVars(T, vtype=GRB.BINARY)
    a_positive = model.addVars(T, vtype=GRB.BINARY)
    for t in T:
    model.addConstr(p[t] >= E-M*(1-p_positive[t])) # truly smaller than, using Epsilon
    model.addConstr(p[t] <= M*p_positive[t])
    model.addConstr(a[t] >= E-M*(1-a_positive[t])) # truly smaller than, using Epsilon
    model.addConstr(a[t] <= M*a_positive[t])
    p_and_a_positive = model.addVars(T)
    for t in T:
    model.addGenConstrAnd(p_and_a_positive[t], [p_positive[t], a_positive[t]])

    a_squared = model.addVars(T)
    for t in T:
    model.addConstr(a_squared[t] == a[t]**2)
    term_1 = model.addVars(T)
    for t in T:
    model.addConstr(beta_1*p[t] == term_1[t])
    term_2 = model.addVars(T)
    for t in T:
    model.addConstr((beta_2*m*a_squared[t]*v[t])/1000 == term_2[t])

    model.setObjective(gp.quicksum(alpha + p_positive[t]*term_1[t] + p_and_a_positive[t]*term_2[t] for t in T))
    0
  • Shaojie Liu
    • Gurobi-versary
    • Conversationalist
    • First Question

    Thank you very much. I think this solution (the code) is very helpful and I can learn a lot from these codes. 

    0

Please sign in to leave a comment.