How to stop presolve from removing variables
回答済みAssume the original model m has 100 variables, and I fix 30 of the 100 variables by setting v.UB=1 , v.LB=1. I want to get the corresponding model with 70 variables. However, if I call p=m.presolve, maybe more than 30 (40, for example) variables will be removed, and i only get model p with 60 variables.
I dont need model p because there are still 10 variables unknown and cannot be mapped back, how can I get the model with 70 variables?
-
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 -
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 -
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 -
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 -
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 -
This is much faster, thanks a lot!
0
サインインしてコメントを残してください。
コメント
6件のコメント