Skip to main content

continues variable that cannot take some values in a range

Answered

Comments

4 comments

  • Jonasz Staszek
    Community Moderator Community Moderator
    Gurobi-versary
    Thought Leader
    First Question

    Hi Ashraf,

    you can perhaps solve this challenge the following way:

    1. We need to add two binary indicator variables per case. One of them will denote the "less than or equal" case, while the other will denote the "more than or equal case. We will call them z.

    2. Then, we need to ensure that exactly one of these variables is set to one (since your variable needs to fall in one of the two ranges). We will add a linear constraint for this end.

    3. Finally we need two indicator constraints to tell Gurobi to set the respective x appropriately.

    In terms of code, it could look something like this:

    z = gp.tupledict()

    for i, var_i in enumerate(restvar):
        z[i, 1] = m.addVar(vtype="B",name=f"indicator_{i}_1")
        z[i, 2] = m.addVar(vtype="B",name=f"indicator_{i}_2")
        
        m.addConstr(z[i, 1] + z[i, 2] == 1)
        
        m.addGenConstrIndicator(z[i, 1], True, x[var_i], gp.GRB.GREATER_EQUAL, upval[i]) 
        m.addGenConstrIndicator(z[i, 2], True, x[var_i], gp.GRB.LESS_EQUAL, lowval[i]) 

    Hope this helps. For future readers, I would also like to point to a great post on OR Stack Exchange about linearizing membership in a linear set.

    Best regards
    Jonasz

    0
  • Ashraf Ali
    Gurobi-versary
    Conversationalist
    First Question

    Thank you Jonasz! That was very helpful.

    On another note, is there a way to report the time the solver took to find a feasible solution other than going back and looking at the log? Like a parameter similar to RunTime for instance.

    0
  • Jonasz Staszek
    Community Moderator Community Moderator
    Gurobi-versary
    Thought Leader
    First Question

    If you are interested in the time taken to find the optimal solution, you can use Python's built-in time module (if you are happy with clock time) - you store the time just before and after the model.optimize() call and then subtract the two and store the difference in a variable.

    For example,

    timestamp = time.time()
    model.optimize()
    duration = time.time() - timestamp

    If the time to find any feasible solution is needed - you could perhaps use callbacks to store the timestamp when each feasible solution was found, and then retrieve it after the optimization. You can find all the relevant information under the link. Perhaps Gurobi staff can point to a more straightforward solution to this question?

    Best regards
    Jonasz

     

    0
  • Matthias Miltenberger
    Gurobi Staff Gurobi Staff

    Hi Ashraf, hi Jonasz,

    Unfortunately, there is no direct or built-in way to query when a solution has been found. You might want to look into Gurobi/grblogtools: Extract and visualize information from Gurobi log files (github.com) to parse your log files and this will also provide you with this piece of information.

    Cheers,
    Matthias

    0

Please sign in to leave a comment.