Optimization with Python: Infeasibility Explanation for Integer Programming with Google OR Tools

Zia
3 min readMar 7, 2022

--

TL;DR

There is no direct interface implemented for infeasible detection for Mixed Integer Programming, but here’s a workaround provided by OR-Tools developers using the CP-SAT solver with the OR-Tools ( >= 8.2 version).

In this workaround, we convert the Integer Problem into a Constraint Programming problem, by adding a boolean variable (called enforcement literal) corresponding to each constraint, which suggests if the constraint is enforced or not. The CP-SAT solver will heuristically find a (local) minimum assignment of false enforcement literals to get a feasible model. We will then check which enforcement literal is False and thus find which constraint is infeasible/conflicting with others.

One remaining problem is that the solver will output all conflicting constraints, which could be a large list, even though there might be only one constraint that is incorrect. We might need to go through all the infeasible constraints to find out which one to modify, or maybe check feasibility every time we add a set of constraints to avoid going through a large list of constraints.

Brief Background about Constraint Programming and CP-SAT

Google provides a few ways to solve CP problems:

Constraint Programming is based on feasibility (finding a feasible solution) rather than optimization (finding an optimal solution) and focuses on the constraints and variables rather than the objective function. In fact, a CP problem may not even have an objective function — the goal may simply be to narrow down a large set of possible solutions to a more manageable subset by adding constraints to the problem.

The CP-SAT solver returns one of the status values shown in below table:

descriptions of status returned by CP-SAT Solver

These are defined in cp_model.proto.

Intuition

In the general sense, it might not be the right approach to throw a series of constraints on a solver and ask the solver to find what is infeasible. The better approach is to instrument your code with a series of boolean values corresponding to the constraints we have. That is, each inequality has enforcement literal.

Then we want a minimal number of false literal to get a feasible model, or maximize the sum of enforcement literals to get a feasible model. We can either set minimizing the (weighted) sum of literals as the objective function, or we can add these enforcement literals as assumptions, a functionality supported by OR-Tools CP solver, into the model. Then we can use the CP solver in OR-Tools which will try to heuristically find a (local) minimum assignment of false literals to get a feasible model.

Approach

Steps of Implementation

1. add boolean variables corresponding to each constraint, which is defined as enforcement literal in OR-Tools. In the end, we want to achieve:

enforcement_literal_1 => constraint_1

enforcement_literal_2 => constraint_2

enforcement_literal_n => constraint_n

2. add enforcement literal to a constraint, we can use the function OnlyEnforceIf(), defined as followed:

This method adds one or more literals (that is, a boolean variable or its negation) as enforcement literals. The conjunction of all these literals determines whether the constraint is active or not. It acts as an implication, so if the conjunction is true, it implies that the constraint must be enforced. If it is false, then the constraint is ignored. BoolOr, BoolAnd, and linear constraints all support enforcement literals.

Notice that in OR-Tools only supports enforcement literals for linear constraints, boolean constraints, and intervals.

3. add enforcement literal to model as assumptions using model.Assumptions()

4. call CpSolver() to solve the model

5. call solver.SufficientAssumptionsForInfeasibility() to display infeasible literal, which would be the infeasible constraints

Implementation Example

Create an infeasible model that constrains every variable to be larger than the others:

Reference

--

--