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?
-
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
Please sign in to leave a comment.
Comments
1 comment