Force expression to only look at a subest of solution values
AnsweredHello!
I'm rather new in working with Python/Gurobi so I have a question that might seem very simple but I can't figure out how to solve it.
Basically I have an expression based on a set of variables. My problem is that while I'm able to set the variables to certain boundary conditions I need to force the expression itself to only allow a subset of possible alternatives.
Example code:
My wish would be for the code to only allow "boben" to chose between being the variables in "bobeh".
However when I run the code I get the following message.
TypeError: 'int' object is not subscriptable
It's very important that the solution looks at the possible given values and finds the best one for the application I'll be using it for later. Simply creating a for loop that goes over all the values and prints the one that gave me the highest value won't resolve the issue I'm facing with my bigger code.
Bests, Bill Edwall.
-
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 -
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 -
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 -
Perfect explination!
Thank you so so much.
You've both been extremely helpful!
Bests, Bill.0
Please sign in to leave a comment.
Comments
4 comments