Writing a complex constraint with multiple for and if conditions
Awaiting user inputI am building a constraint with multiple for and if loops. Need help resolving error or writing this in a better way...
I have 'K' and 'T' as lists, 'C[k]' as parameter defined with gurobi multidict, 'q' as integer variable and 'a' as binary variable..
x = m.addConstrs(
(
q.sum("*", k, "*", T[i]) <= C[k] * a.sum(k, "*", T[j])
for k in K
for j, t in enumerate(T)
if (a.sum(k, "*", T[j]) >= 1)
for i, t in enumerate(T)
if (i >= j)
),
name="x",
)
I initially did this without [ if (a.sum(k,'*',T[j]) >= 1) ], no code errors.. But I understand the values of q is iterated in each loop.
Eg: if a.sum(k,'*',T[0]) =1, then q.sum('*',k,'*',T[i]) is C[k] for all T.. When a.sum(k,'*',T[1]) =0, then q.sum('*',k,'*',T[1] becomes 0 which in previous iteration was C[k]. But I always want the highest value to be retained for q. Please correct me if my interpretation is wrong here...
I have another constraint in my model: y = m.addConstrs((a.sum(k,'*','*') <= 1 for k in K), name = 'y')
When [if (a.sum(k,'*',T[j]) >= 1] is part of constraint, I get error: Constraint has no bool value (are you trying "lb <= expr <= ub"?). I understand that I maybe cannot use a variable in condition.
I tried this using indicator: x = m.addConstrs(( (a.sum(k,'*',T[j]) == 1) >> (q.sum('*',k,'*',T[i]) <= C[k]*a.sum(k,'*',T[j])) for k in K for j,t in enumerate(T)
for i,t in enumerate(T)
if (i >= j) ), name ='x')
I get the error: Indicator constraints can only be triggered by a single binary variable at a given value
Is there a better alternative to do this?
-
Official comment
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 try Gurobot, our chatbot interface offering instant, expert-level support. -
Hi Priyanka,
Do you want to implement the constraint below?
\[\mbox{if} ~~ \sum_{l} a_{k, l, T_j} \geq 1 \rightarrow \sum_{l, m} q_{l,k,m,T_i} \leq c_k \sum_{l} a_{k, l, T_j}, ~~ \forall k, j, i ~(i \geq j)\]
Since the indicator variable in the signature of the Model.addGenConstrIndicator() method should be a binary variable, you can define auxiliary binary variables \(z_{k,j}\) to implement the above constraint using one additional intermediate constraint as below:
\[\mbox{if} ~~ \sum_{l} a_{k, l, T_j} \geq 1 \rightarrow z_{k,j} = 1, ~~ \forall k, j\]
\[\mbox{if} ~~ z_{k,j} = 1 \rightarrow \sum_{l, m} q_{l,k,m,T_i} \leq c_k \sum_{l} a_{k, l, T_j}, ~~ \forall k, j, i ~(i \geq j)\]
The second constraint matches the signature of the Model.addGenConstrIndicator() method where the indicator variable \(z_{k,j}\) is binary and it can be directly implemented.
The first constraint is logically equivalent to its contrapositive:
\[\mbox{if} ~~ z_{k,j} \neq 1 \rightarrow \sum_{l} a_{k, l, T_j} \ngeq 1 ~~ \forall k, j\]
which can be written as below because the variables \(a\) are binaries. This constraint now matches the signature of the Model.addGenConstrIndicator() method and can be directly implemented.
\[\mbox{if} ~~ z_{k,j} = 0 \rightarrow \sum_{l} a_{k, l, T_j} = 0 ~~ \forall k, j\]
For which constraint, did you get the error \(\texttt{Constraint has no bool value ...}\)?
Best regards,
Maliheh
0
Post is closed for comments.
Comments
2 comments