scip

Defining OR-constraint in mixed-integer problem with SCIP


I'm trying to use the python interface of SCIP tool (https://github.com/scipopt/PySCIPOpt) to solve a mixed-integer optimization problem.

I want to define an OR-constraint with three constraints, but only one of them must be satisfied.

For example, I want to minimize a variable x with three constraints x>=1, x>=2, x>=3, but only one of them must be valid, and then minimize the value of x. Of course the result should be x=1.

However the OR-constraint API addConsOr requires both the constraint list and result variable (resvar, resultant variable of the operation). While I can provide the list of constraints, I don't know the meaning of result variable in the second function parameter. When I set the second parameter to a new variable, the following code cannot run and result in segmentation fault.

from pyscipopt import Model

model = Model()
x = model.addVar(vtype = "I")
b = model.addVar(vtype="B")
model.addConsOr([x>=1, x>=2, x>=3], b)
model.setObjective(x, "minimize")
model.optimize()
print("Optimal value:", model.getObjVal())

Also, setting the second variable to True also gets segmentation fault.

model.addConsOr([x>=1, x>=2, x>=3], True)

Solution

  • What you are describing is not an OR-constraint. An or-constraint is a constraint that takes into account a set of binary variables and gets the result as an OR of these values, as explained in the SCIP documentation.

    What you want is a general disjunctive constraint. Those exist in SCIP as SCIPcreateConsDisjunction but are not wrapped in the Python API yet. Fortunately, you can extend the API yourself quite easily. Simply add the correct function to scip.pxd and define the wrapper in scip.pyx. Just look at how it is done for the existing constraint types and do it the same way. The people over at the PySCIPopt GitHub will be happy if you create a pull-request with your changes.