Skip to main content

adding quadratic expression in indicator constraints

Answered

Comments

7 comments

  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Vaibhav,

    "nested_sum > 1" doesn't work because you can't use strict inequalities, you can change it to ">=" but it will still fail because you can't use quadratic expression in indicator expressions, which is why nested_sum==0 doesn't work.

    Your last approach should work.  What is the error you are seeing?  Please paste the full error message, including traceback.

    - Riley

    1
  • Vaibhav Dixit
    First Comment
    First Question

    Hi Riley,

    Thanks for your reply. It is not showing complete errors.

    KeyError

    Traceback (most recent call last) /tmp/ipykernel_770156/583479396.py in <module>

    18 # model.addConstr((y[i] == 0) >>(nested_sum==0))

    19 ---> 20 model.addConstr(x1[i]==nested_sum)

    21 model.addConstr((y[i]==Integer(1))>>(x1[i]==Integer(0)))

    22 model.update()

    KeyError: 1
    How can I check actual error?

    -Vaibhav

    0
  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Vaibhav,

    "KeyError: 1" is the actual error.

    It's pointing to this line: model.addConstr(x1[i]==nested_sum)

    There is only one key in this line, and that is the i in x1[i].  The error message is telling you x1[1] does not exist.

    You can run print(x) and check what the keys of this tupledict are.

    - Riley

    1
  • Vaibhav Dixit
    First Comment
    First Question

    Hi,

    Thanks, it's working now.

    I have another doubt, till now I only worked on quadratic equations something like
    $ \sum_{j=0}^{n-1}P[i,j]* (\sum_{ (k \in lst[i]) } m[k,0] ) == 0 $ for each i in range(1,n) 

    i.e nesed_sum is a quadratic expression but now I'm dealing with an expression of degree 3 like,

    $ \sum_{j=0}^{n-1} P[i,j]* (\sum_{l=0}^{n-1} P[i,l]* (\sum_{ (k \in lst[i]) } m[k,0])) == 0$ for each i in range(n) 
    Can Gurobi handle constraints having a three-degree expression?

    Now I have model.addConstr( nested_sum == above expression ==0 ) but it is showing TypeError: unsupported operand type(s) for *: 'Var' and 'generator'.

    0
  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Vaibhav,

    Can Gurobi handle constraints having a three-degree expression?

    No not yet, you will need to introduce additional variables and reformulate so that it is no more than degree 2.  See this post for an example, https://support.gurobi.com/hc/en-us/community/posts/360072027392-How-to-deal-with-a-product-of-3-different-decision-variables-in-a-term

    TypeError: unsupported operand type(s) for *: 'Var' and 'generator'.

    This is unrelated to the three-degree expression.  Have a look at where * is used in your code.  Somewhere you are multiplying a variable by a generator expression - which doesn't make sense.  Most of the time this mistake occurs because the user intends to sum the results of the generator expression but forgets to.

    - Riley

    0
  • Vaibhav Dixit
    First Comment
    First Question

    Hi,

    I have three constraints say

    constr1 : gp.quicksum(P[1,t] for t in range(1,n)) >= 1)

    constr2 : gp.quicksum(x[i,1] + x[i,2] for i in lst) == len(lst))

    constr3 : gp.quicksum(x[i,2] for i in lst) == 1 + 2* rnd[cnt])

    How can I write such that :

    (1) constr1 = True implies constr2 = True OR constr2 = True

    (2) constr1 = True implies constr2 = True AND constr2 = True

    model.addConstr((y[count] == 0) >> (gp.quicksum(P[1,t] for t in range(1,n)) == 0))
    model.addConstr((y[count] == 1) >> (gp.quicksum(x[i,1] + x[i,2] for i in lst) == len(lst)))
    model.addConstr((y[count] == 1) >> (gp.quicksum(x[i,2] for i in lst) == 1 + 2* rnd[cnt]))
     
    I think adding constraints like this represents part (2). Pls correct me if I'm wrong. But I don't
    know how to represent part (1).
    My actual problem is: I have 4 constrs, say 1,2,3,4. I want, Constr1 = True implies (Constr2 = True ) AND (Constr3 = True OR Constr4 = True).
    i.e Constr1 is true implies Constr2 is true and at least one of Constr3, Constr4 is true.
    Thanks.
     
    0
  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Vaibhav,

    I think adding constraints like this represents part (2).

    Yes, what you have looks correct.
     
    For part (1) I'd introduce two auxiliary variables, aux1, aux2 (or whatever names you like) and formulate
    model.addConstr((aux1 == 1) >> (gp.quicksum(x[i,1] + x[i,2] for i in lst) == len(lst)))
    model.addConstr((aux2 == 1) >> (gp.quicksum(x[i,2] for i in lst) == 1 + 2* rnd[cnt]))
    model.addConstr((y[count] == 1) >> (aux1 + aux2 >= 1))
    - Riley
     
    0

Please sign in to leave a comment.