Skip to main content

is there a repetitive manner in Gurobi within the pyton?

Answered

Comments

12 comments

  • Official comment
    Simranjit Kaur
    • Gurobi Staff Gurobi Staff
    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?.
  • Jaromił Najman
    • Gurobi Staff Gurobi Staff

    Hi Qikun,

    So, I want ask you whether the gurobi+python can achieve this above.

    Yes, Gurobi + Python can achieve the above. However, you don't have to implement your own algorithm because Gurobi can handle constraints of the form \(Q^2 = x\cdot y\). You just have to set the NonConvex parameter to 2.

    The idea of how Gurobi solves problems holding this kind of constraints is actually very similar to the algorithm you described, see the NonConvex webinar for more details. The \(\delta\) tolerance in your case can be set via the FeasibilityTol parameter. Please note that the FeasibilityTol parameter sets the tolerance for all constraints and not only these specific equality constraints. As you already pointed out, providing tight finite bounds for all variables participating in nonlinear terms is crucial for the convergence speed of the algorithm.

    Best regards,
    Jaromił

    0
  • Cass C
    • Gurobi-versary
    • Curious
    • Conversationalist

    Hi Najman

    So many thanks for your answering which is very useful for me. But I wound like to ask, because the case I have been analysing is a quite large scale of LP problem with a quadratic constraint, and this is why I want replace the expression of nonlinear to a SOCP constraint. But as you mentioned, the equation can be just directly expressed in Nonlinear form in Gurobi without any implementing. However, without relaxation via McCormick to let the term (in the right hand of the equation)  to a linear expression, the case will be difficult to solve due to the computation burden, isn't it?

    Many thanks

    Qikun

     

    0
  • Jaromił Najman
    • Gurobi Staff Gurobi Staff

    Hi Qikun,

    However, without relaxation via McCormick to let the term (in the right hand of the equation) to a linear expression, the case will be difficult to solve due to the computation burden, isn't it?

    Gurobi constructs McCormick relaxations internally, see our NonConvex presentation. The complexity and computation burden is comparable to the algorithm you described but with the addition of Gurobi's arsenal of algorithms and heuristics on top of that.

    Best regards,
    Jaromił

    0
  • Cass C
    • Gurobi-versary
    • Curious
    • Conversationalist

    Hi Jaromił

    Many thanks for your replying, but by the way, I still need repeat optimizing the model for several times. The output is required to compared with some defined constant in my case, and if it is not acceptable, I will run it until it meet my satisfactory.

    So I want to know, is the python+gurobi has such a function to reach this.

    many thanks,

    Qikun

    0
  • Jaromił Najman
    • Gurobi Staff Gurobi Staff

    Hi Qikun,

    After an optimization run is finished, you can access the value of several model, variable, and constraint attributes. Is this what you are looking for?

    Best regards,
    Jaromił

    0
  • Cass C
    • Gurobi-versary
    • Curious
    • Conversationalist

    Hi, Jaromił, 

    Thanks for answering.

    The question is I have defined some constant in optimization as:

    phi_Lim=defaultdict(dict)
    for a in A:
    fromNode=arcPar[a]['fnode']
    toNode=arcPar[a]['tnode']
    phi_Lim[a]['plus_lb']=gasNodePar[fromNode]['Nmin'] + gasNodePar[toNode]['Nmin']
    phi_Lim[a]['plus_ub']=gasNodePar[fromNode]['Nmax'] + gasNodePar[toNode]['Nmax']
    phi_Lim[a]['minus_lb']=gasNodePar[fromNode]['Nmin'] - gasNodePar[toNode]['Nmax']
    phi_Lim[a]['minus_ub']=gasNodePar[fromNode]['Nmax'] - gasNodePar[toNode]['Nmin']



    then these constant is used in optimization, after the optimization finished, i need update
    several times.

    k=1



    for k in range (50):

    phi_Lim[a]['plus_lb']*=(1+0.2)
    phi_Lim[a]['plus_ub']*=(1-0.2)
    phi_Lim[a]['minus_lb']*=(1+0.2)
    phi_Lim[a]['minus_ub']*=(1-0.2)

    k+=1

    m.update()
    m.optimize()
    else:
    break


    However, these data are not updated in optimization, so I would like to know how to solve this.

    Many thank!

    0
  • Jaromił Najman
    • Gurobi Staff Gurobi Staff

    Hi,

    Thank you for the clarification.

    To change the right-hand side of a constraint, you have to directly access the constraint attribute RHS where the constant is used. You can update the coefficients via the chgCoeff function. An example would be

    import gurobipy as gp
    from gurobipy import GRB

    m = gp.Model("mip1")

    x = m.addVar(vtype=GRB.BINARY, name="x")
    y = m.addVar(vtype=GRB.BINARY, name="y")

    constantForRHS = 10
    constantForCoefficientX = 5
    constantForCoefficientY = 3

    # construct constraint 5 x + 3 y <= 10
    constr = m.addConstr(constantForCoefficientX * x + constantForCoefficientY * y <= constantForRHS, name="myConstr")

    # do something
    # [...]
    # update constants
    constantForRHS *= 3
    constantForCoefficientX *= 2
    constantForCoefficientY *= 4

    # update constraint to 10 x + 12 y <= 30
    constr.RHS = constantForRHS
    m.chgCoeff(constr, x, constantForCoefficientX)
    m.chgCoeff(constr, y, constantForCoefficientY)

    Best regards,
    Jaromił

     

    0
  • Cass C
    • Gurobi-versary
    • Curious
    • Conversationalist

    Hi Jaromił

    many thanks for answering and I have updated mu model by using change coefficient and RHS as:

    tol_1={}

    tol_2={}
    for a in A:
    i = arcPar[a]['fnode'] # Starting node
    j = arcPar[a]['tnode'] # Ending node
    for t in T:

    if arcPar[a]['arcType']==0:

    tol_1[(a,t)]=abs(pr[i,t].X**2-pr[(j,t)].X**2-psi[(a,t)].X)/pr[i,t].X**2
    #tol_1[(a,t)]=abs((pr[i,t].X**2-pr[(j,t)].X**2)-psi[(a,t)].X)/(pr[i,t].X**2-pr[(j,t)].X**2)
    tol_2[(a,t)]=ma.sqrt(abs(wp[(a,t)].X-wn[(a,t)].X))*x[(a,t)].X




    while tol_1[(a,t)]>0.1 and k<1:

    constantForCoefficient_1*=(1-n**k)
    constantForCoefficient_2*=(1+n**k)
    constantForCoefficient_3*=(1-n**k)
    constantForCoefficient_4*=(1-n**k)


    m.chgCoeff(constr_4, phi_minus[(a,t)], constantForCoefficient_1)
    m.chgCoeff(constr_5, phi_minus[(a,t)], constantForCoefficient_1)

    m.chgCoeff(constr_3, phi_minus[(a,t)], constantForCoefficient_2)
    m.chgCoeff(constr_6, phi_minus[(a,t)], constantForCoefficient_2)

    m.chgCoeff(constr_4, phi_minus[(a,t)], constantForCoefficient_3)
    m.chgCoeff(constr_6, phi_minus[(a,t)], constantForCoefficient_3)

    m.chgCoeff(constr_3, phi_minus[(a,t)], constantForCoefficient_4)
    m.chgCoeff(constr_5, phi_minus[(a,t)], constantForCoefficient_4)

    constantForRHS_2=constantForCoefficient_4*constantForCoefficient_2
    constantForRHS_3=constantForCoefficient_1*constantForCoefficient_3
    constantForRHS_4=constantForCoefficient_1*constantForCoefficient_4
    constantForRHS_5=constantForCoefficient_2*constantForCoefficient_3

    constr_3.RHS=constantForRHS_2
    constr_4.RHS=constantForRHS_3
    constr_5.RHS=constantForRHS_4
    constr_6.RHS=constantForRHS_5
    k+=1
    m.update()
    m.optimize()

    while tol_2[(a,t)]-f[(a,t)].X>0.3 and s<5:
    constantForCoefficient_6*=0.8
    m.chgCoeff(constr_1, phi_minus[(a,t)], constantForCoefficient_6)
    m.chgCoeff(constr_2, phi_minus[(a,t)], constantForCoefficient_6)
    m.update()
    m.optimize()
    s+=1

    I have defined variables with an index[(a,t)], and the code above is wrote below the last m.optimize(), and i want use tol_1 and tol_2 to test the acceptance of each variable, and if it not meet the requirement or iteration number <k, the model will continue run and update coefficients for the variable.

    But the problem is the tol_1 and tol_2 seem not changed a lot, so I am wondering whether the code above is correct.

    Many thanks

    Qikun

     

    0
  • Jaromił Najman
    • Gurobi Staff Gurobi Staff

    Hi Qikun,

    I think you should print the optimal solution after each optimization run to better track the changes in solution point values. This might help you in debugging your code. It might be best to write the optimal solution of each iteration to a file via the ResultFile parameter and analyze the changes step by step manually.

    Note that if you change a coefficient in a way that the previous optimal solution is still feasible and the formulation is not relaxed, then there will be no change in the solution point.

    Best regards,
    Jaromił

    0
  • Cass C
    • Gurobi-versary
    • Curious
    • Conversationalist

    Jaromił:

    many thanks!

    I have updated my code and there are two questions from me.

    My case is a two dimensional optimization with an index of a,t,  where a represents the location and t represents the time step. There are some constraints, and take one of them as an example:

    for a in A:
    for t in T:
    c1=m.addConstr(phi_plus_min[(a,t)]*phi_minus[(a,t)] + phi_plus[(a,t)]*phi_minus_min[(a,t)]-psi[(a,t)] <=constantForRHS_1[(a,t)],"c3")

    where the phi_plus_min[(a,t)] and phi_minus_min[(a,t)] are coefficient and phi_minus[(a,t)], phi_plus[(a,t)] are variables. If I would like to change the coefficient of a variable(e.g., phi_minus[(a,t)]), then I am required to use m.chgCoeff():

    for a in A:
    i = arcPar[a]['fnode'] # Starting node
    j = arcPar[a]['tnode'] # Ending node
    for t in T:
    if arcPar[a]['arcType']==0 and tol_1[(a,t)]>0.1:
                phi_minus_max[(a,t)]*=(1-0.1**k)
    phi_minus_min[(a,t)]*=(1-0.1**k)
    phi_plus_max[(a,t)]*=(1-0.1**k)
    phi_plus_min[(a,t)]*=(1-0.1**k)

    m.chgCoeff(c3,phi_minus[(a,t)],phi_plus_min[(a,t)])
    m.chgCoeff(c3,phi_plus[(a,t)],phi_minus_min[(a,t)])
    constantForRHS_1[(a,t)]=phi_plus_min[(a,t)]*phi_minus_min[(a,t)]
    c3.RHS=constantForRHS_1[(a,t)]

    However, when I updated the value via m.update() and did not optimize the case, but after running the model, it noted that AttributeError: Unable to retrieve attribute 'X'. Note that the model has been optimized before changing the coefficient, but I wonder why m.update() will lead to AttributeError: Unable to retrieve attribute 'X'.

    Many thanks

    Qikun

    0
  • Jaromił Najman
    • Gurobi Staff Gurobi Staff

    Hi Qikun,

    Calling the model.update() function after changing a coefficient may violate the solution point saved in the X attribute. Thus, the X attribute is no longer available. In this case, it is best to do all coefficient changes first and call the update function after all changes have been performed. In your case, you should not have to call the update function at all. Please note that the optimize function implicitly calls the update function.

    Best regards,
    Jaromił

    0

Post is closed for comments.