I have a pyscipopt.Model
variable model
, encoding an integer program with linear constraints.
I want to evaluate some solution on all rows of the constraint matrix. The only way I thought of is to use model.getSolVal()
to get solution values on modified variables, and compute the dot product with the rows of the modified constraint matrix manually.
The following snippet extracts the nonzero coefficients of a constraint in the model:
constr = model.getConss()[0]
coeff_dict = model.getValsLinear(constr)
It runs fine before presolving, but after presolving (or just optimizing) I get the following error
Warning: 'coefficients not available for constraints of type ', 'logicor'.
My current solution is to disable presolving completely, in which case the variables aren't modified. Can I avoid that?
I am assuming you want to do something with the row activities and not just check whether your solution is feasible?
getValsLinear
is only usable for linear constraints. In presolving SCIP upgrades linear constraints to some more specialized constraint types (in your case logicor).
There exists a function in SCIP called SCIPgetConsVals
that does what you want getValsLinear
to do (it gets you the values for all constraints that have a linear representation). However, that function is not wrapped in PySCIPopt
yet.
You can easily wrap that function yourself (and even head over to https://github.com/scipopt/PySCIPOpt and create a Pull-request). The other option is to read a settings file that forbids the linear constraints from being upgraded.
constraints/linear/upgrade/logicor = FALSE
constraints/linear/upgrade/indicator = FALSE
constraints/linear/upgrade/knapsack = FALSE
constraints/linear/upgrade/setppc = FALSE
constraints/linear/upgrade/xor = FALSE
constraints/linear/upgrade/varbound = FALSE
would be the settings you need. That way you still have presolving just without constraint upgrades.