Using result of a decisionvariable for further computations
回答済みHello,
I have the following problem (I am working with Python):
I have a quadratic constraint with binary variables x and y, which computes the sum of a product of x*y*some value of a dictionary, where only one x and one y is 1. The result of the sum is between -5 and 5. J1 and J2 have about 100 entries each. It looks like
model.addConstr(z == quicksum(y[j1] * x[j2] * dictionary1(j1,j2) for j1 in J1 for j2 in J2))
Now I need to add another value, which depends on this result. It is a lookup in some second dictionary and would simplified look like:
model.addConstr(a == dictionary2[z])) s.t. the endresult will look like:
model.addConstr(result == z+a)
As I am a beginner in Gurobi, I am not sure, whether it is the same problem as this one and how I need to change my model to implement it correctly:
Or whether it is not that similar and there is a trick or something that I do not see.
Thanks in advance
Simon
-
正式なコメント
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?. -
Hi Simon,
The current formulation won't work because you cannot use model variables to index other variables/parameters. However, we can model this as follows. Let \( c \) denote the first dictionary, \( d \) the second dictionary, and \( v \) the variable you call "result" in your code. We add the following constraint to the model:
$$\begin{align*}v &= \sum_{i \in J_1} \sum_{j \in J_2} y_i x_j(c_{ij} + d_{c_{ij}}). \end{align*}$$
Because exactly one \( y_i \) and one \( x_j \) are \( 1 \), exactly one \( y_i x_j \) term in the summation is equal to \( 1 \) (the rest are \( 0 \)). Thus, the equation simplifies to \( v = c_{ij} + d_{c_{ij}} \), where \( y_i = x_j = 1 \).
Translated to Python code, this is:
model.addConstr(result == quicksum(y[i] * x[j] * (dictionary1[i,j] + dictionary2[dictionary1[i,j]]) for i in J1 for j in J2))Could you try this out? Thanks!
Eli
0 -
Hey Eli,
Thank you for your reply. Your answer would perfectly fit my simplified model. Unfortunately, my simplified model is too loose, because I made a mistake simplifying it and so the suggested solution wouldn't work for me. Sorry for that!
I'll give it a more precise try, please have a look at the following:
I have an array, let's say 'membersArray' and I need to calculate the sum for each member. If this array has 3 entries,
I would get three constraints, which I can sum up to: result == z[firstMember]+z[secondMember]+z[thirdMember].
In my python code, it looks like:
for member in membersArray:
model.addConstr(z[member] == quicksum((y[j1]*x[member,j2] * dictionary1[j1,j2] for j1 in J1 for j2 in J2)This 'result' value, which I could define as:
model.addConstr(result == quicksum(z[member] for member in membersArray)
is what I need to look up in the second dictionary (for the only y which is 1, so I don't need the j2 for this).
The second dictionary look-up would look like:
dictionary2[result]
As I cannot use model variables to index other variables or parameters, this wouldn't be feasible, would it?
Simon
0 -
As the result is some Integer value between -5 and 5, I thought about something like an implication. But the only way I could imagine this is as follows (with an example value of 3):
model.addConstr(result==3 <= u_3)
where u is some binary variable for each of the 11 outcomes. But of course this would also not work, as 'result' has no bool value. Is there any workaround?
Simon
0 -
Hi Simon,
This should still be possible with a different formulation. Again, let \( v \) be the variable you call "result," and let \( d \) be the second dictionary. In addition to the constraints you have written, we introduce variables \( u \in \{0,1\}^{11} \) (there are 11 possible values for \( v \)). Then, we add the following constraints:
$$\begin{align*}\sum_{i = 1}^{11} (i-6) u_i &= v \\ \sum_{i = 1}^{11} u_i &= 1. \end{align*}$$
The idea is that exactly one the \( u_i \) variables will be equal to \( 1 \), and this index \( i \) will satisfy \( v = i - 6 \). Finally, we introduce a new variable \( w \) and set it equal to the value of "dictionary2[result]" with the constraint:
$$w = \sum_{i = 1}^{11} d_{i - 6} u_i.$$
In Python, we can equivalently write this as:
# Integers from -5 to 5
M = range(-5,6)
# Add auxiliary variables
u = model.addVars(M, vtype=GRB.BINARY, name="u")
w = model.addVar(lb=-GRB.INFINITY, name="w")
# Exactly one u_i is 1, such that result = i
model.addConstr(u.sum() == 1)
model.addConstr(result == quicksum(i*u[i] for i in M))
# Set w equal to dictionary2[result]
model.addConstr(w == u.prod(dictionary2))Does this work? Thanks!
Eli
0 -
Hello Eli,
Thanks again for your reply. Your approach helped me to understand my problem and I was able to solve it :)
Simon
0
投稿コメントは受け付けていません。
コメント
6件のコメント