Skip to main content

Force expression to only look at a subest of solution values

Answered

Comments

4 comments

  • Silke Horn
    Gurobi Staff Gurobi Staff

    Hi Bill,

    Welcome to the Gurobi Community!

    I am not quite sure I understand your question. Do you want your expression boben to be allowed to take exactly the values in the array bobeh (1, 2, or 3)? In this case, you could define an auxiliary variable that is integral with lower bound 1 and upper bound 3; e.g.:

    aux = m.addVar(vtype=GRB.INTEGER, lb=1, ub=3)
    m.addConstr(boben == aux)

    If the allowed range for your expression is more complicated (e.g. a list of non-consecutive integer values), this will be more difficult to model. You could then introduce binary variables for each allowed value. E.g. if only the values 1 or 3 are allowed, you could do something like the following:

    allowed_values = [1,3]

    # add one binary var for each allowed value
    aux = m.addVars(allowed_values, vtype=GRB.BINARY)
    # make sure exactly one of those binary vars is 1
    m.addConstr(aux.sum() == 1)

    # make sure boben takes one of the allowed values
    m.addConstr(boben == quicksum(aux[i] * i for i in allowed_values))

    These variables and constraints will ensure that your expression boben takes one of the values 1 or 3.

     

    One more thing: I noticed that you chose the same name "bob" for both variables x and y. You should always use unique names for variables and constraints. (Otherwise, Gurobi will use default names instead.)

    1
  • Bill Edwall
    Gurobi-versary
    Conversationalist
    First Question

    Thank you so much for the quick reply. 
    I tested your code and it does exactly what I want it to do! 
    Thank you so much!! I've been scratching my head at this for hours!

    Could you however do me one last favour and explain how thesse two contraints function so that I can understand their underlying mechanism? 

    I belive that If I understand how the first one operates I'll understand the other one.

    Either way have a wonderful day and thank you so much!

    # make sure exactly one of those binary vars is 1
    m.addConstr(aux.sum() == 1)

    # make sure boben takes one of the allowed values
    m.addConstr(boben == quicksum(aux[i] * i for i in allowed_values))
    0
  • Eli Towle
    Gurobi Staff Gurobi Staff

    Hi Bill,

    If we let \( x_1 \) and \( x_3 \) represent the integer "aux" variables and \( y \) represent the "boben" variable, the mathematical equivalent of this programmatic formulation is:

    $$\begin{align*}x_1 + \phantom{3}x_3 &= 1 \\ x_1 + 3x_3 &= y\end{align*}$$

    Because \( x_1 \) and \( x_3 \) are both binary, the first constraint says that exactly one of these variables must be take on a value of \( 1 \) and the other must be \( 0 \). Then, the second constraint sets the \( y \) variable ("boben') equal to the index of the binary variable that is equal to \( 1 \). For instance, if \( x_1 = 1 \) and \( x_3 = 0 \), then we end up with \( y = 1 \). On the other hand, if \( x_3 = 1 \) and \( x_1 = 0 \), then we have \( y = 3 \).

    Does this help? Thanks!

    Eli

    0
  • Bill Edwall
    Gurobi-versary
    Conversationalist
    First Question

    Perfect explination! 
    Thank you so so much.
    You've both been extremely helpful!

    Bests, Bill. 

    0

Please sign in to leave a comment.