Skip to main content

How to stop presolve from removing variables

Answered

Comments

6 comments

  • Riley Clement
    • Gurobi Staff

    Hi Liu,

    As luck would have it I wrote some Python code to do this recently for LPs and MILPs:

    def _replace_column(m, v):
        col = m.getCol(v)
        for i in range(col.size()):
            con = col.getConstr(i)
            con.RHS -= col.getCoeff(i)*v.lb
        m.remove(v)
    m.update()

    def replace_fixings(m):
    m.update()
        vars = m.getVars()
        for v in vars: 
          if (v.lb == v.ub):
                _replace_column(m, v)

    m = ... # create model
    replace_fixings(m)

    - Riley

     

    0
  • liu heng
    • Gurobi-versary
    • Conversationalist
    • Investigator

    Thank you Riley, I have tried this but there is still some issues: replace_fixings(m) spent much more time than m.presolve() (in fact my model has much more than 100 variables), I wonder if there is some faster way? Looking forward to your reply and appreciate it

    0
  • Riley Clement
    • Gurobi Staff

    The update() function in the _replace_column function gets called often which will cause it to be slow. If you remove it though then the RHS values will be incorrect for any constraint which contains more than one fixed variable. One alternative is to maintain a mapping of constraint names to RHS values, and adjust those instead, then use them to replace the RHS values in the constraints at the end.

    0
  • Riley Clement
    • Gurobi Staff

    I'll see if I can put together a faster method with our matrix API.  This one was only ever meant for toy models.

     

    0
  • Riley Clement
    • Gurobi Staff

    Hi Liu,

    This should run much faster:

    vars = m.getVars()
    constrs = m.getConstrs()
    A = m.getA().tocsc()
    RHS = m.getAttr("RHS", constrs)

    fixed_inds = [i for i,v in enumerate(vars) if v.lb == v.ub]
    fixed_vars = [v for v in vars if v.lb == v.ub]
    fixed_vals = [v.lb for v in fixed_vars]
    m.setAttr("RHS", constrs, RHS - A[:,fixed_inds]@fixed_vals)
    m.remove(fixed_vars)
    m.update()
    m.remove([con for con in constrs if m.getRow(con).size() == 0])

    - Riley

    0
  • liu heng
    • Gurobi-versary
    • Conversationalist
    • Investigator

    This is much faster, thanks a lot!

    0

Please sign in to leave a comment.