# 8.3 Debugging infeasibility¶

When solving an optimization problem one typically expects to get an optimal solution, but in some cases, either by design, or (most frequently) due to an error in the formulation, the problem may become infeasible (have no solution at all).

This section

describes the intuitions behind infeasibility,

helps to debug (unexpectedly) infeasible problems using the command line tool and by inspecting infeasibility reports and problem data by hand,

gives some hints for how to modify the formulation to identify the reasons for infeasibility.

If, instead, you want to fetch an infeasibility certificate directly using Optimizer API for Python, see the tutorial in Sec. 6.13 (Retrieving infeasibility certificates).

An infeasibility certificate is only available for continuous problems, however the hints in Sec. 8.3.4 (Suggestions) apply to a large extent also to mixed-integer problems.

## 8.3.1 Numerical issues¶

Infeasible problem status may be just an artifact of numerical issues appearing when the problem is badly-scaled, barely feasible or otherwise ill-conditioned so that it is unstable under small perturbations of the data or round-off errors. This may be visible in the solution summary if the infeasibility certificate has poor quality. See Sec. 8.1.2 (Solution summary) for how to diagnose that and Sec. 8.2 (Addressing numerical issues) for possible hints. Sec. 8.2.3 (Typical pitfalls) contains examples of situations which may lead to infeasibility for numerical reasons.

We refer to Sec. 8.2 (Addressing numerical issues) for further information on dealing with those sort of issues. For the rest of this section we concentrate on the case when the solution summary leaves little doubt that the problem solved by the optimizer actually is infeasible.

## 8.3.2 Locating primal infeasibility¶

As an example of a primal infeasible problem consider minimizing the cost of transportation between a number of production plants and stores: Each plant produces a fixed number of goods, and each store has a fixed demand that must be met. Supply, demand and cost of transportation per unit are given in Fig. 8.1.

The problem represented in Fig. 8.1 is infeasible, since the total demand

exceeds the total supply

If we denote the number of transported goods from plant \(i\) to store \(j\) by \(x_{ij}\), the problem can be formulated as the LP:

Solving problem (8.1) using **MOSEK** will result in an infeasibility status. The infeasibility certificate is contained in the dual variables an can be accessed from an API. The variables and constraints with nonzero solution values form an infeasible subproblem, which frequently is very small. See Sec. 12.1.2 (Infeasibility for Linear Optimization) or Sec. 12.2.2 (Infeasibility for Conic Optimization) for detailed specifications of infeasibility certificates.

A short infeasibility report can also be printed to the log stream. It can be turned on by setting the parameter `iparam.infeas_report_auto`

to `onoffkey.on`

. This causes **MOSEK** to print a report on variables and constraints which are involved in infeasibility in the above sense, i.e. have nonzero values in the certificate. The parameter `iparam.infeas_report_level`

controls the amount of information presented in the infeasibility report. The default value is \(1\). For the above example the report is

```
Primal infeasibility report
Problem status: The problem is primal infeasible
The following constraints are involved in the primal infeasibility.
Index Name Lower bound Upper bound Dual lower Dual upper
0 s0 none 200 0 1
2 s2 none 1000 0 1
3 d0 1100 1100 1 0
4 d1 200 200 1 0
The following bound constraints are involved in the primal infeasibility.
Index Name Lower bound Upper bound Dual lower Dual upper
5 x33 0 none 1 0
6 x34 0 none 1 0
```

The infeasibility report is divided into two sections corresponding to constraints and variables. It is a selection of those lines from the problem solution which are important in understanding primal infeasibility. In this case the constraints `s0`

, `s2`

, `d0`

, `d1`

and variables `x33`

, `x34`

are of importance because of nonzero dual values. The columns `Dual lower`

and `Dual upper`

contain the values of dual variables \(s_l^c\), \(s_u^c\), \(s_l^x\) and \(s_u^x\) in the primal infeasibility certificate (see Sec. 12.1.2 (Infeasibility for Linear Optimization)).

In our example the certificate means that an appropriate linear combination of constraints `s0`

, `s1`

with coefficient \(s_u^c=1\), constraints `d0`

and `d1`

with coefficient \(s_u^c-s_l^c=0-1=-1\) and lower bounds on `x33`

and `x34`

with coefficient \(-s_l^x=-1\) gives a contradiction. Indeed, the combination of the four involved constraints is \(x_{33}+x_{34}\leq -100\) (as indicated in the introduction, the difference between supply and demand).

It is also possible to extract the infeasible subproblem with the command-line tool. For an infeasible problem called `infeas.lp`

the command:

```
mosek -d MSK_IPAR_INFEAS_REPORT_AUTO MSK_ON infeas.lp -info rinfeas.lp
```

will produce the file `rinfeas.bas.inf.lp`

which contains the infeasible subproblem. Because of its size it may be easier to work with than the original problem file.

Returning to the transportation example, we discover that removing the fifth constraint \(x_{12} = 200\) makes the problem feasible. Almost all undesired infeasibilities should be fixable at the modeling stage.

## 8.3.3 Locating dual infeasibility¶

A problem may also be *dual infeasible*. In this case the primal problem is usually unbounded, meaning that feasible solutions exists such that the objective tends towards infinity. For example, consider the problem

which is dual to (8.1) (and therefore is dual infeasible). The dual infeasibility report may look as follows:

```
Dual infeasibility report
Problem status: The problem is dual infeasible
The following constraints are involved in the dual infeasibility.
Index Name Activity Objective Lower bound Upper bound
5 x33 -1 none 2
6 x34 -1 none 1
The following variables are involved in the dual infeasibility.
Index Name Activity Objective Lower bound Upper bound
0 y1 -1 200 none 0
2 y3 -1 1000 none 0
3 y4 1 1100 none none
4 y5 1 200 none none
```

In the report we see that the variables `y1`

, `y3`

, `y4`

, `y5`

and two constraints contribute to infeasibility with non-zero values in the `Activity`

column. Therefore

is the dual infeasibility certificate as in Sec. 12.1.2 (Infeasibility for Linear Optimization). This just means, that along the ray

which belongs to the feasible set, the objective value \(100t\) can be arbitrarily large, i.e. the problem is unbounded.

In the example problem we could

Add a lower bound on

`y3`

. This will directly invalidate the certificate of dual infeasibility.Increase the objective coefficient of

`y3`

. Changing the coefficients sufficiently will invalidate the inequality \(c^Ty^*>0\) and thus the certificate.

## 8.3.4 Suggestions¶

Primal infeasibility

When trying to understand what causes the unexpected primal infeasible status use the following hints:

Remove the objective function. This does not change the infeasibility status but simplifies the problem, eliminating any possibility of issues related to the objective function.

Remove cones, semidefinite variables and integer constraints. Solve only the linear part of the problem. Typical simple modeling errors will lead to infeasibility already at this stage.

Consider whether your problem has some obvious necessary conditions for feasibility and examine if these are satisfied, e.g. total supply should be greater than or equal to total demand.

Verify that coefficients and bounds are reasonably sized in your problem.

See if there are any obvious contradictions, for instance a variable is bounded both in the variables and constraints section, and the bounds are contradictory.

Consider replacing suspicious equality constraints by inequalities. For instance, instead of \(x_{12} = 200\) see what happens for \(x_{12}\geq 200\) or \(x_{12}\leq 200\).

Relax bounds of the suspicious constraints or variables.

For integer problems, remove integrality constraints on some/all variables and see if the problem solves.

Remember that variables without explicitly initialized bounds are fixed at zero.

Form an

**elastic model**: allow to violate constraints at a cost. Introduce slack variables and add them to the objective as penalty. For instance, suppose we have a constraint\[\begin{split}\begin{array}{lr} \minimize & c^Tx, \\ \st & a^Tx\leq b. \end{array}\end{split}\]which might be causing infeasibility. Then create a new variable \(y\) and form the problem which contains:

\[\begin{split}\begin{array}{lr} \minimize & c^Tx+y, \\ \st & a^Tx\leq b+y. \end{array}\end{split}\]Solving this problem will reveal by how much the constraint needs to be relaxed in order to become feasible. This is equivalent to inspecting the infeasibility certificate but may be more intuitive.

If you think you have a feasible solution or its part, fix all or some of the variables to those values. Presolve will propagate them through the model and potentially reveal more localized sources of infeasibility.

Dump the problem in PTF or LP format and verify that the problem that was passed to the optimizer corresponds to the problem expressed in the high-level modeling language, if any such was used.

Dual infeasibility

When trying to understand what causes the unexpected dual infeasible status use the following hints:

Verify that the objective coefficients are reasonably sized.

Check if no bounds and constraints are missing, for example if all variables that should be nonnegative have been declared as such etc.

Strengthen bounds of the suspicious constraints or variables.

Remember that constraints without explicitly initialized bounds are free (no bound).

Form an series of models with decreasing bounds on the objective, that is, instead of objective

\[\minimize\ c^Tx\]solve the problem with an additional constraint such as

\[c^Tx = -10^5\]and inspect the solution to figure out the mechanism behind arbitrarily decreasing objective values. This is equivalent to inspecting the infeasibility certificate but may be more intuitive.

Dump the problem in PTF or LP format and verify that the problem that was passed to the optimizer corresponds to the problem expressed in the high-level modeling language, if any such was used.

Please note that modifying the problem to invalidate the reported certificate does *not* imply that the problem becomes feasible — the reason for infeasibility may simply *move*, resulting a problem that is still infeasible, but for a different reason. More often, the reported certificate can be used to give a hint about errors or inconsistencies in the model that produced the problem.