Skip to main content

Formulate Second Order Cone Constraints in Gurobi

Answered

Comments

9 comments

  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Can Yin,

    You may need to look at what other constraints you have.

    The following example, based on your problem, does not give a non-convex warning and the acknowledges the constraint as a SOCC in the resulting log

    I = 3
    T = 2

    m = gp.Model()
    x = m.addVar()
    z = m.addVar()
    y = m.addVars(I,T)


    m.addConstr( z**2 >= x**2 + gp.quicksum(y[i,t]**2 for i in range(I) for t in range(T)) , name = "")
    m.params.presolve=0
    m.optimize()

    You could try setting

    m.params.NonConvex=2
    m.params.presolve=0

    and see if your log mentions the SOCC?

    - Riley

     

    0
  • CAN YIN
    Gurobi-versary
    First Question
    Conversationalist

    Hello Riley

     

    Thank you very much for your help, I am currently not very sure where is the problem happening. However, all the constraints except for the second-order cone constraints should be linear constraints. Also, Gurobi also didn't give me a warning saying the problem was non-convex when I commented out the second-order constraints, which made me assume I made a mistake in the second-order constraints. 

    Besides, I do a simplification for the easy present, x, and z are actually introduced auxiliary variables while z = a+b and x = a-b, would this be a possible making mistake? 

    And also might I know what's the difference between using 

    y[i,t] and y[i][t]

    I tried to run your code and it runs well, however, when I change it to y[i][t], it fails and give error like this:

    m.addConstr( z**2 >= x**2 + gp.quicksum(y[i][t]**2 for i in range(I) for t in range(T)) , name = "")
    ~^^^

    would this be the potential mistakes that I am making?

     

    Thanks for reading, and again thank you very much for your help!

    0
  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Can Yin,

    How large is your complete code?  I think I'd need to see it in order to be of any more help with respect to the non-convexity.

     

    And also might I know what's the difference between using 

    y[i,t] and y[i][t]

    y[i][t] shouldn't work if y is a tupledict.  You can run

    type(y)

    to confirm what type y is.  If you created it as an MVar then your syntax would work, although if you're not using matrix multiplication to create constraints then I'd suggest just using tupledicts.

    - Riley

    0
  • CAN YIN
    Gurobi-versary
    First Question
    Conversationalist

    Hello Riley

    Thanks for your support and thank you for your explanation

    The complete code for this model is roughly 120 lines and includes a lot of lines only for comments or blank, 

    And yes, I created most of my Variables as MVar, would it cause a problem if I create MVar for 1-dimensional variables?

    Thanks for reading

    0
  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Can Yin,

    It won't be incorrect to use MVar in this way, just possibly slow.  But if you're not experiencing large model build times then there isn't much motivation for you to change.

    Feel free to post your code here if you're willing.

    - Riley

    0
  • CAN YIN
    Gurobi-versary
    First Question
    Conversationalist

    Hello Riley

    Thanks for your help and sorry for the late reply. 

    I have made some changes to your code and found out that when I change the default lower bound of x and z into infinity negative like below, the problem will give me " Q matrix is not positive semi-definite (PSD). Set NonConvex parameter to 2 to solve model." 

    Seems to me that the problem happens in my lower-bound setting, Might I know are there any ways that I can deal with it? or does it only accept non-negative x and z inside?

    I = 3
    T = 2
    K = 3

    m = gp.Model()

    x = m.addVars(K, lb = float("-inf"),  ub = float("inf"), vtype = GRB.CONTINUOUS)
    z = m.addVars(K, lb = float("-inf"),  ub = float("inf"), vtype = GRB.CONTINUOUS)
    y = m.addVars(K, I, T)

    for k in range(K):
    m.addConstr( z[k]**2 >= x[k]**2 + gp.quicksum(y[k,i,t]**2 for i in range(I) for t in range(T)) , name = "")

    m.params.presolve=0
    m.optimize()
     
    Thanks for reading and hope you have a good day!
    Yin Can
    0
  • CAN YIN
    Gurobi-versary
    First Question
    Conversationalist

    Hello Riley

    Sorry, I just found out where I made the mistake. 

    I should make z a non-negative variable to make it become a second-order cone constraint, and it seems fine right now. 

    Thanks for your help and thanks for your support!

    Yin Can

    0
  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Yin Can,

    No problem!  I was going to point out as a simpler analogy the case of y^2 >= x^2:

    Clearly the set is not convex, however if you restrict y >= 0 you have a convex set, or if you restrict y <= 0 you have a convex set.

    If your model needed to allow z to take negative or positive values then you could model it as a disjunction where a binary variable is introduced to indicate whether z is negative or positive (or equivalently use the addGenConstrAbs()  method to link a strictly positive z variable that participates in the cone constraint with a new variable, that can be negative or positive).

    - Riley

    0
  • CAN YIN
    Gurobi-versary
    First Question
    Conversationalist

    Thank you very much!

    0

Please sign in to leave a comment.