Skip to main content

Solving a very Large QIP

Answered

Comments

5 comments

  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Derek,

    Your objective has many terms of the form

    sum constant_i * Locations[IND,PHI,127] * variable_i

    Could you try reformulating the obejctive by introducing an additional auxiliary variable and equality constraint to get

    aux_var = sum constant_i * variable_i

    and then replace the above sum by

    Locations[IND,PHI,127] * aux_var

    Note that auxvar needs to be a free continuous variable. You can apply this to all such terms that you have. From what I see, you have this for constellation for every variable. After you apply the reformulation, could you please share the MPS/LP file?

    In addition to the above reformulation, you might want to set DegenMoves=0. If you think that a the primal bound is not good enough, you might want to experiment with the NoRelHeurTime parameter.

    Since you have many products with binary variable, you might also want to test the PreQLinearize parameter.

    Best regards, 
    Jaromił

    0
  • Derek Long
    First Comment
    First Question

    Hi Jaromił,

    Thanks for your response. Currently, the objective looks like the following (where `self.distances`, `self.teams`, and `self.timesteps` are arrays of constants, and `self.l` are the Locations[] variables):

    obj = gp.quicksum(self.distances[k][j] * self.l[i, k, t - 1] * self.l[i, j, t] for t in self.timesteps[1:]
                    for j in self.teams for k in self.teams for i in self.teams if self.distances[k][j] > 1e-6)

    Would you have an idea of how to reformulate this per your description?

    Kind regards,
    Derek

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Derek,

    Would you have an idea of how to reformulate this per your description?

    You could use the QuadExpr object and successively build up your objective function in a for-loop while adding auxiliary variables and equalities. Something like the following pseudo-code should give you an idea

    obj = gp.QuadExpr(0)
    outer for-loop:
    aux_linexpr = gp.LinExpr(0)

    inner for-loop to construct auxiliary linear expression
    aux_linexpr.add(constant * variable)

    aux_var = gp.addVar(lb=-GRB.INFINITY, name="auxvar")
    model.addConstr(aux_linexpr == aux_var, "name="auxconstr")

    obj.add(loopvariable * aux_var)

    # possibly add some linear part to obj

    model.setObjective(obj)

    Best regards, 
    Jaromił

    0
  • Derek Long
    First Comment
    First Question

    Thanks Jaromił. Please find the updated .mps file here (I've checked that the incumbent solution has the same objective as before). 

    Kind regards,
    Derek

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Derek,

    The best settings I can see so far for the updated model are

    The first three parameters make sure that only the Barrier method is used to solve node relaxations. It looks like Simplex really struggles on this model. I don't have any good reason for why it is the case.

    DegenMoves avoids a quite expensive feasible point heuristic which is performed right before the B&B tree. In your case, it is extraordinary expensive as it uses Simplex moves internally.

    Presolve 2 activates more presolve reduction. This intuitively makes sense as your model is really big for a MIQCP.

    PreQLinearize controls the way how products with binary variables are handled.

    Please note that even with the above parameters, the model is far from convergence.

    I think that only some reformulation or maybe additional constraints can help. Maybe our webinar on strong MIP formulations is helpful here.

    Maybe you could try to perform some presolve yourself. If any such information is available, you could fix sets of decision variables to simplify the model.

    Best regards, 
    Jaromił

    0

Please sign in to leave a comment.