6.1. Irreducible Inconsistent Subsystem (IIS)

When you build a model to solve optimization problems in practice, you may encounter infeasible problems. The infeasible problems are caused by conflicts between constraints and/or variable bounds. It is important to analyze infeasible problems and identify the key conflicting constraints and/or variable bounds during the application of the solver.

Given an infeasible model, an Irreducible Inconsistent Subsystem (IIS) is a minimal subset of constraints and/or variable bounds that cause the infeasibility. An IIS has two properties: (1) it is infeasible, and (2) it is irreducible, i.e., removing any constraint or variable bound would make the subsystem feasible.

MindOpt provides an API for IIS calculation. You can call this API to analyze infeasible problems. Then, you can correct or remove constraints in the IIS to make optimization problems feasible. Note that the IIS may not be unique in an infeasible problem. If multiple IISs exist, you need to adjust the optimization problem several times to make it feasible. For example:

\[\begin{split}\text{c}_1: ~~ x_1 \leq 1 \\ \text{c}_2: ~~ x_1 \geq 2 \\ \text{c}_3: ~~ x_2 \leq 3 \\ \text{c}_4: ~~ x_2 \geq 4 \\\end{split}\]

In this example, we can easily know that \(c_1\) and \(c_2\) form an IIS, and \(c_3\) and \(c_4\) form another IIS. After you remove one constraint from both IISs, the problem becomes feasible.

The following part provides a more practical example to describe how to obtain an IIS with MindOpt. In the following infeasible constraint system:

\[\begin{split}\text{Constraints:} & & \\ & -0.5 x_0 + x_1 &>= 0.5 \\ & 2 x_0 - x_1 &>= 3 \\ & 3 x_0 + x_1 &<= 6 \\ & 3 x_3 - x_4 &<= 2 \\ & x_0 + x_4 &<= 10 \\ & x_0 + 2 x_1 + x_3 &<= 14 \\ & x_1 + x_3 &>= 1 \\ \text{Bounds:} & & \\ & 5 <= x_3 & \\ & 0 <= x_4 <= 2 &\end{split}\]

The former three constraints form an IIS, and the fourth constraint and the upper and lower bounds of variables form another IIS.

Note

At present, MindOpt uses a filtering algorithm to find IISs. The filtering algorithm can find an IIS within a short time but cannot ensure that this IIS is the smallest among all. In addition, if you adjust the sequence of constraints, MindOpt may generate different IISs.

Note

In practice, if the problem remains infeasible after fixing an IIS, users can input the modified model into the IIS solving API, and fix the next IIS. This process can be repeated until all conflicts are fixed, resulting in a feasible problem.

Since calculating an IIS can be computationally expensive for larger models, particularly MIP models, the computation may be interrupted before completion, and then, MindOpt will return the infeasible subsystem found to that point. This subsystem may not satisfy the irreducibility property.

After an IIS computation is finished, MindOpt provides an API to write the IIS to a .ilp format file. The file format is the same as the .lp file, with an empty objective function, and the constraints and variable bounds that form the IIS.

The IISRow constraint attribute and the IISCol variable attribute indicate whether the corresponding model element is a member of the computed IIS. You can obtain information about the results of the IIS computation via these attributes.

The following part describes how to use MindOpt in a C/C++/Python environment to obtain an IIS of infeasible problems.

6.1.1. IIS Computation in C

First, create an optimization problem and set parameters by referring to LP Modeling and Optimization in C.

 89    /* Create and start environment. */
 90    MDOemptyenv(&env);
 91    MDOstartenv(env);
 92
 93    /* Create optimization model with variables. */
 94    CHECK_RESULT(MDOnewmodel(env, &m, MODEL_NAME, NCOLS, obj, lb, ub, NULL, colname));
 95
 96    /* Input constraints. */
 97    CHECK_RESULT(MDOaddrangeconstrs(m, NROWS, cbeg[NROWS], cbeg, cind, cval, lhs, rhs, rowname));
 98
 99    /* Specify objective sense. */
100    CHECK_RESULT(MDOsetintattr(m, MODEL_SENSE, MDO_MINIMIZE));
101    
102    /* Optimize the input problem. */
103    CHECK_RESULT(MDOoptimize(m));

Then, when the optimization problem is infeasible, use computeIIS() to compute an IIS, use MDOwrite() to write the IIS to a .ilp format file, and query the IISRow constraint attribute and the IISCol variable attribute so as to populate the computed IIS.

107    /* Populate optimziation result. */
108    CHECK_RESULT(MDOgetintattr(m, STATUS, &status));
109    if (status == MDO_INFEASIBLE || status == MDO_INF_OR_UBD) 
110    {
111        printf("Optimizer terminated with an primal infeasible status.\n");
112        printf("Start to compute an Irreducible Inconsistent Subsystem (IIS).\n");
113        /* Compute an IIS and write the result into file (in ILP format). */
114        CHECK_RESULT(MDOcomputeIIS(m));
115        printf("Writing IIS into file (ILP format).\n");
116        CHECK_RESULT(MDOwrite(m, "./test1.ilp"));
117        /* Populate the computed IIS. */
118        printf("Populating all variable/constraint bounds participate in the computed IIS.\n");
119        CHECK_RESULT(MDOgetintattrarray(m, IISROW, 0, NROWS, &(*ival)));
120        for (i = 0; i < NROWS; ++i)
121        {
122            switch (ival[i])
123            {
124            case 2:
125                printf("The upper bound of inequality constraint [%s] participates in the IIS.\n", rowname[i]);
126                break;
127            case 3:
128                printf("The lower bound of inequality constraint [%s] participates in the IIS.\n", rowname[i]);
129                break;
130            case 5:
131                printf("[%s] is an equality constraint, and both its lower bound and upper bound participate in the IIS.\n", rowname[i]);
132                break;
133            }
134        }
135        CHECK_RESULT(MDOgetintattrarray(m, IISCOL, 0, NCOLS, &(*ival)));
136        for (j = 0; j < NCOLS; ++j)
137        {
138            switch (ival[j])
139            {
140            case 2:
141                printf("The upper bound of variable [%s] participates in the IIS.\n", colname[j]);
142                break;
143            case 3:
144                printf("The lower bound of variable [%s] participates in the IIS.\n", colname[j]);
145                break;
146            case 5:
147                printf("[%s] is a fixed variable, and both its lower bound and upper bound participate in the IIS.\n", colname[j]);
148                break;
149            }
150        }
151    }

Example MdoLoIIS.c provides complete source code:

  1/**
  2 *  Description
  3 *  -----------
  4 *
  5 *  Linear optimization.
  6 *   - Compute IIS of an infeasible problem.
  7 *
  8 *  Formulation
  9 *  -----------
 10 *
 11 *  Minimize
 12 *  Obj:
 13 *  Subject To
 14 *  c0:  -0.500000000 x0 + x1 >= 0.500000000
 15 *  c1:  2 x0 - x1 >= 3
 16 *  c2:  3 x0 + x1 <= 6
 17 *  c3:  3 x3 - x4 <= 2 <- conflicts with variable bounds listed below!
 18 *  c4:  x0 + x4 <= 10
 19 *  c5:  x0 + 2 x1 + x3 <= 14
 20 *  c6:  x1 + x3 >= 1
 21 *  Bounds
 22 *   5 <= x3
 23 *   0 <= x4 <= 2
 24 *  End
 25 */
 26#include <stdio.h>
 27#include "Mindopt.h"
 28#include <stdlib.h>
 29
 30#define RELEASE_MEMORY  \
 31    MDOfreemodel(m);    \
 32    MDOfreeenv(env);
 33#define CHECK_RESULT(code) { int res = code; if (res != 0) { fprintf(stderr, "Bad code: %d\n", res); RELEASE_MEMORY; return (res); } }
 34#define NROWS        7
 35#define NCOLS        5
 36#define MODEL_NAME  "lp_iis"
 37#define MODEL_SENSE "ModelSense"
 38#define STATUS      "Status"
 39#define ROWNAME     "RowName"
 40#define COLNAME     "ColName"
 41#define IISROW      "IISRow"
 42#define IISCOL      "IISCol"
 43#define MAXDIM      (NROWS>NCOLS ? NROWS:NCOLS)
 44
 45int main(void) 
 46{
 47    /* Variables. */
 48    MDOenv *env;
 49    MDOmodel *m;
 50    int i, j, status;
 51    int ival[MAXDIM];
 52
 53    /* Model data. */
 54    int cbeg[] = {0, 2, 4, 6, 8, 10, 13, 15};
 55    int cind[] = 
 56    {
 57        0,   1, 
 58        0,   1,
 59        0,   1,
 60        3,   4,
 61        0,   4,
 62        0,   1,   3,
 63        1,   3  
 64    };
 65    double cval[] =
 66    {
 67       -0.5, 1,
 68        2,  -1,
 69        3,   1,
 70        3,  -1,
 71        1,   1,
 72        1,   2,   1,
 73        1,   1
 74    };
 75    double lhs[] = 
 76    {          
 77        0.5, 3.0, -MDO_INFINITY, -MDO_INFINITY, -MDO_INFINITY, -MDO_INFINITY, 1.0 
 78    };
 79    double rhs[] = 
 80    {
 81        MDO_INFINITY, MDO_INFINITY, 6.0, 2.0, 10.0, 14.0, MDO_INFINITY
 82    };
 83    const char* rowname[] = { "c0", "c1" , "c2" , "c3" , "c4" , "c5" , "c6" };
 84    double lb[] =  {          0.0,          0.0,          0.0,          5.0, 0.0 };
 85    double ub[] =  { MDO_INFINITY, MDO_INFINITY, MDO_INFINITY, MDO_INFINITY, 2.0 };
 86    double obj[] = {          0.0,          0.0,          0.0,          0.0, 0.0 };
 87    const char* colname[] = { "x0", "x1", "x2", "x3", "x4" };
 88
 89    /* Create and start environment. */
 90    MDOemptyenv(&env);
 91    MDOstartenv(env);
 92
 93    /* Create optimization model with variables. */
 94    CHECK_RESULT(MDOnewmodel(env, &m, MODEL_NAME, NCOLS, obj, lb, ub, NULL, colname));
 95
 96    /* Input constraints. */
 97    CHECK_RESULT(MDOaddrangeconstrs(m, NROWS, cbeg[NROWS], cbeg, cind, cval, lhs, rhs, rowname));
 98
 99    /* Specify objective sense. */
100    CHECK_RESULT(MDOsetintattr(m, MODEL_SENSE, MDO_MINIMIZE));
101    
102    /* Optimize the input problem. */
103    CHECK_RESULT(MDOoptimize(m));
104
105    /* Populate optimziation result. */
106    CHECK_RESULT(MDOgetintattr(m, STATUS, &status));
107    if (status == MDO_INFEASIBLE || status == MDO_INF_OR_UBD) 
108    {
109        printf("Optimizer terminated with an primal infeasible status.\n");
110        printf("Start to compute an Irreducible Inconsistent Subsystem (IIS).\n");
111        /* Compute an IIS and write the result into file (in ILP format). */
112        CHECK_RESULT(MDOcomputeIIS(m));
113        printf("Writing IIS into file (ILP format).\n");
114        CHECK_RESULT(MDOwrite(m, "./test1.ilp"));
115        /* Populate the computed IIS. */
116        printf("Populating all variable/constraint bounds participate in the computed IIS.\n");
117        CHECK_RESULT(MDOgetintattrarray(m, IISROW, 0, NROWS, &(*ival)));
118        for (i = 0; i < NROWS; ++i)
119        {
120            switch (ival[i])
121            {
122            case 2:
123                printf("The upper bound of inequality constraint [%s] participates in the IIS.\n", rowname[i]);
124                break;
125            case 3:
126                printf("The lower bound of inequality constraint [%s] participates in the IIS.\n", rowname[i]);
127                break;
128            case 5:
129                printf("[%s] is an equality constraint, and both its lower bound and upper bound participate in the IIS.\n", rowname[i]);
130                break;
131            }
132        }
133        CHECK_RESULT(MDOgetintattrarray(m, IISCOL, 0, NCOLS, &(*ival)));
134        for (j = 0; j < NCOLS; ++j)
135        {
136            switch (ival[j])
137            {
138            case 2:
139                printf("The upper bound of variable [%s] participates in the IIS.\n", colname[j]);
140                break;
141            case 3:
142                printf("The lower bound of variable [%s] participates in the IIS.\n", colname[j]);
143                break;
144            case 5:
145                printf("[%s] is a fixed variable, and both its lower bound and upper bound participate in the IIS.\n", colname[j]);
146                break;
147            }
148        }
149    }
150
151    /* Free up model memory. */
152    RELEASE_MEMORY;
153
154    return 0;
155}

6.1.2. IIS Computation in C++

First, create an optimization problem and set parameters by referring to LP Modeling and Optimization in C++.

36        /* Create an empty model for optimization. */
37        MDOEnv env = MDOEnv();
38        MDOModel model = MDOModel(env);
39
40        /* Add variables. */
41        vector<MDOVar> x;
42        x.push_back(model.addVar(0.0, MDO_INFINITY, 0.0, MDO_CONTINUOUS, "x0"));
43        x.push_back(model.addVar(0.0, MDO_INFINITY, 0.0, MDO_CONTINUOUS, "x1"));
44        x.push_back(model.addVar(0.0, MDO_INFINITY, 0.0, MDO_CONTINUOUS, "x2"));
45        x.push_back(model.addVar(5.0, MDO_INFINITY, 0.0, MDO_CONTINUOUS, "x3"));
46        x.push_back(model.addVar(0.0, 2.0,          0.0, MDO_CONTINUOUS, "x4"));
47
48        /* Add constraints. */
49        vector<MDOConstr> constr;
50        constr.push_back(model.addConstr(-0.5 * x[0]        + x[1]                   >= 0.5,  "c0"));
51        constr.push_back(model.addConstr( 2.0 * x[0]        - x[1]                   >= 3.0,  "c1"));
52        constr.push_back(model.addConstr( 3.0 * x[0]        + x[1]                   <= 6.0,  "c2"));
53        constr.push_back(model.addConstr(                          3.0 * x[3] - x[4] <= 2.0,  "c3"));
54        constr.push_back(model.addConstr(       x[0]                          + x[4] <= 10.0, "c4"));
55        constr.push_back(model.addConstr(       x[0] + 2.0 * x[1]      + x[3]        <= 14.0, "c5"));
56        constr.push_back(model.addConstr(                    x[1]      + x[3]        >= 1.0,  "c6"));
57
58        /* Optimize the input problemodel. */
59        model.optimize();

Then, when the optimization problem is infeasible, use MDOModel::computeIIS() to compute an IIS, use MDOModel::write() to write the IIS to a .ilp format file, and query the IISRow constraint attribute and the IISCol variable attribute so as to populate the computed IIS.

 61        /* Populate optimziation result. */
 62        int status = model.get(MDO_IntAttr_Status);
 63        if (status == MDO_INFEASIBLE || status == MDO_INF_OR_UBD) 
 64        {
 65            cout << "Optimizer terminated with an primal infeasible status." << endl;
 66            cout << "Start to compute an Irreducible Inconsistent Subsystem (IIS)." << endl;
 67            /* Compute an IIS and write it into file (in ILP format). */
 68            model.computeIIS();
 69            cout << "Writing IIS into file (ILP format)." << endl;
 70            model.write("./test1.ilp");
 71            /* Populate the computed IIS. */
 72            cout << "Populating all row/column bounds participate in the computed IIS." << endl;
 73            for (auto c : constr)
 74            {
 75                string name = c.get(MDO_StringAttr_ConstrName);
 76                switch (c.get(MDO_IntAttr_IISConstr))
 77                {
 78                case 2:
 79                    cout << "The upper bound of inequality constraint [" << name << "] participates in the IIS." << endl;
 80                    break;
 81                case 3:
 82                    cout << "The lower bound of inequality constraint [" << name << "] participates in the IIS." << endl;
 83                    break;
 84                case 5:
 85                    cout << "[" << name << "] is an equality constraint, and both its lower bound and upper bound participate in the IIS." << endl;
 86                    break;
 87                }
 88            }
 89            for (auto v : x)
 90            {
 91                string name = v.get(MDO_StringAttr_VarName);
 92                switch (v.get(MDO_IntAttr_IISVar))
 93                {
 94                case 2:
 95                    cout << "The upper bound of variable [" << name << "] participates in the IIS." << endl;
 96                    break;
 97                case 3:
 98                    cout << "The lower bound of variable [" << name << "] participates in the IIS." << endl;
 99                    break;
100                case 5:
101                    cout << "[" << name << "] is a fixed variable, and both its lower bound and upper bound participate in the IIS." << endl;
102                    break;
103                }
104            }
105        }

Example MdoLoIIS.cpp provides complete source code:

  1/**
  2 *  Description
  3 *  -----------
  4 *
  5 *  Linear optimization.
  6 *   - Compute IIS of an infeasible problem.
  7 *
  8 *  Formulation
  9 *  -----------
 10 *
 11 *  Minimize
 12 *  Obj:
 13 *  Subject To
 14 *  c0:  -0.500000000 x0 + x1 >= 0.500000000
 15 *  c1:  2 x0 - x1 >= 3
 16 *  c2:  3 x0 + x1 <= 6
 17 *  c3:  3 x3 - x4 <= 2 <- conflicts with variable bounds listed below!
 18 *  c4:  x0 + x4 <= 10
 19 *  c5:  x0 + 2 x1 + x3 <= 14
 20 *  c6:  x1 + x3 >= 1
 21 *  Bounds
 22 *   5 <= x3
 23 *   0 <= x4 <= 2
 24 *  End
 25 */
 26#include "MindoptCpp.h"
 27#include <iostream>
 28#include <map>
 29
 30using namespace std;
 31
 32int main(int argc, char *argv[]) 
 33{
 34    try 
 35    {
 36        /* Create an empty model for optimization. */
 37        MDOEnv env = MDOEnv();
 38        MDOModel model = MDOModel(env);
 39
 40        /* Add variables. */
 41        vector<MDOVar> x;
 42        x.push_back(model.addVar(0.0, MDO_INFINITY, 0.0, MDO_CONTINUOUS, "x0"));
 43        x.push_back(model.addVar(0.0, MDO_INFINITY, 0.0, MDO_CONTINUOUS, "x1"));
 44        x.push_back(model.addVar(0.0, MDO_INFINITY, 0.0, MDO_CONTINUOUS, "x2"));
 45        x.push_back(model.addVar(5.0, MDO_INFINITY, 0.0, MDO_CONTINUOUS, "x3"));
 46        x.push_back(model.addVar(0.0, 2.0,          0.0, MDO_CONTINUOUS, "x4"));
 47
 48        /* Add constraints. */
 49        vector<MDOConstr> constr;
 50        constr.push_back(model.addConstr(-0.5 * x[0]        + x[1]                   >= 0.5,  "c0"));
 51        constr.push_back(model.addConstr( 2.0 * x[0]        - x[1]                   >= 3.0,  "c1"));
 52        constr.push_back(model.addConstr( 3.0 * x[0]        + x[1]                   <= 6.0,  "c2"));
 53        constr.push_back(model.addConstr(                          3.0 * x[3] - x[4] <= 2.0,  "c3"));
 54        constr.push_back(model.addConstr(       x[0]                          + x[4] <= 10.0, "c4"));
 55        constr.push_back(model.addConstr(       x[0] + 2.0 * x[1]      + x[3]        <= 14.0, "c5"));
 56        constr.push_back(model.addConstr(                    x[1]      + x[3]        >= 1.0,  "c6"));
 57
 58        /* Optimize the input problemodel. */
 59        model.optimize();
 60
 61        /* Populate optimziation result. */
 62        int status = model.get(MDO_IntAttr_Status);
 63        if (status == MDO_INFEASIBLE || status == MDO_INF_OR_UBD) 
 64        {
 65            cout << "Optimizer terminated with an primal infeasible status." << endl;
 66            cout << "Start to compute an Irreducible Inconsistent Subsystem (IIS)." << endl;
 67            /* Compute an IIS and write it into file (in ILP format). */
 68            model.computeIIS();
 69            cout << "Writing IIS into file (ILP format)." << endl;
 70            model.write("./test1.ilp");
 71            /* Populate the computed IIS. */
 72            cout << "Populating all row/column bounds participate in the computed IIS." << endl;
 73            for (auto c : constr)
 74            {
 75                string name = c.get(MDO_StringAttr_ConstrName);
 76                switch (c.get(MDO_IntAttr_IISConstr))
 77                {
 78                case 2:
 79                    cout << "The upper bound of inequality constraint [" << name << "] participates in the IIS." << endl;
 80                    break;
 81                case 3:
 82                    cout << "The lower bound of inequality constraint [" << name << "] participates in the IIS." << endl;
 83                    break;
 84                case 5:
 85                    cout << "[" << name << "] is an equality constraint, and both its lower bound and upper bound participate in the IIS." << endl;
 86                    break;
 87                }
 88            }
 89            for (auto v : x)
 90            {
 91                string name = v.get(MDO_StringAttr_VarName);
 92                switch (v.get(MDO_IntAttr_IISVar))
 93                {
 94                case 2:
 95                    cout << "The upper bound of variable [" << name << "] participates in the IIS." << endl;
 96                    break;
 97                case 3:
 98                    cout << "The lower bound of variable [" << name << "] participates in the IIS." << endl;
 99                    break;
100                case 5:
101                    cout << "[" << name << "] is a fixed variable, and both its lower bound and upper bound participate in the IIS." << endl;
102                    break;
103                }
104            }
105        }
106    } 
107    catch (MDOException &e) 
108    {
109        cerr << "Error code = " << e.getErrorCode() << endl;
110        cerr << e.getMessage() << endl;
111    } 
112    catch (...) 
113    {
114        cerr << "Error during optimization." << endl;
115    }
116
117    return 0;
118}

6.1.3. IIS Computation in Python

First, create an optimization problem and set parameters by referring to LP Modeling and Optimization in Python.

36    try:
37        # Add Variables.
38        x = []
39        x.append(model.addVar(0.0, float('inf'), 'C', "x0"))
40        x.append(model.addVar(0.0, float('inf'), 'C', "x1"))
41        x.append(model.addVar(0.0, float('inf'), 'C', "x2"))
42        x.append(model.addVar(5.0, float('inf'), 'C', "x3"))
43        x.append(model.addVar(0.0, 2.0,          'C', "x4"))
44
45        # Add Constraints.
46        constr = []
47        constr.append(model.addConstr(-0.5 * x[0]       + x[1]                    >= 0.5,  "c0"))
48        constr.append(model.addConstr( 2.0 * x[0]       - x[1]                    >= 3.0,  "c1"))
49        constr.append(model.addConstr( 3.0 * x[0]       + x[1]                    <= 6.0,  "c2"))
50        constr.append(model.addConstr(                          3.0 * x[3] - x[4] <= 2.0,  "c3"))
51        constr.append(model.addConstr(       x[0]                          + x[4] <= 10.0, "c4"))
52        constr.append(model.addConstr(       x[0] + 2.0 * x[1]      + x[3]        <= 14.0, "c5"))
53        constr.append(model.addConstr(       x[1] +                   x[3]        >= 1.0,  "c6"))
54
55        # Optimize the input problem.
56        model.optimize()

Then, when the optimization problem is infeasible, use mindoptpy.MdoModel.compute_iis() to compute an IIS, use Model.write() to write the IIS to a .ilp format file, and query the IISRow constraint attribute and the IISCol variable attribute so as to populate the computed IIS.

57        # Run IIS.
58        if model.status == MDO.INFEASIBLE or model.status == MDO.INF_OR_UBD:
59            print("Optimizer terminated with an primal infeasible status.")
60            print("Start to compute an Irreducible Inconsistent Subsystem (IIS).")
61            # Compute an IIS and write it to file (in ILP format).
62            model.computeIIS()
63            print("Writing IIS into file (ILP format).")
64            model.write("./test1.ilp")
65            print("Populating all bounds participate in the computed IIS.")
66            for c in constr:
67                status = c.IISConstr
68                name = c.ConstrName
69                if status == 2:
70                    print(f"The upper bound of inequality constraint [{name}] participates in the IIS.")
71                elif status == 3:
72                    print(f"The lower bound of inequality constraint [{name}] participates in the IIS.")
73                elif status == 5:
74                    print(f"[{name}] is an equality constraint, and both its lower bound and upper bound participate in the IIS.")
75            for v in x:
76                status = v.IISVar
77                name = v.VarName
78                if status == 2:
79                    print(f"The upper bound of variable [{name}] participates in the IIS.")
80                elif status == 3:
81                    print(f"The lower bound of variable [{name}] participates in the IIS.")
82                elif status == 5:
83                    print(f"[{name}] is a fixed variable, and both its lower bound and upper bound participate in the IIS.")

Example mdo_lo_iis.py provides complete source code:

 1"""
 2/**
 3 *  Description
 4 *  -----------
 5 *
 6 *  Linear optimization.
 7 *   - Compute an IIS on an infeasible problem.
 8 * 
 9 *  Formulation
10 *  -----------
11 *
12 *  Minimize
13 *  Obj:
14 *  Subject To
15 *  c0:  -0.500000000 x0 + x1 >= 0.500000000
16 *  c1:  2 x0 - x1 >= 3
17 *  c2:  3 x0 + x1 <= 6
18 *  c3:  3 x3 - x4 <= 2 <- conflit with variable bounds below!
19 *  c4:  x0 + x4 <= 10
20 *  c5:  x0 + 2 x1 + x3 <= 14
21 *  c6:  x1 + x3 >= 1
22 *  Bounds
23 *   5 <= x3
24 *   0 <= x4 <= 2
25 *  End
26 */
27"""
28from mindoptpy import *
29
30if __name__ == "__main__":
31
32    # Create an empty model for optimization.
33    model = Model("IIS_LP")
34
35    try:
36        # Add Variables.
37        x = []
38        x.append(model.addVar(0.0, float('inf'), 'C', "x0"))
39        x.append(model.addVar(0.0, float('inf'), 'C', "x1"))
40        x.append(model.addVar(0.0, float('inf'), 'C', "x2"))
41        x.append(model.addVar(5.0, float('inf'), 'C', "x3"))
42        x.append(model.addVar(0.0, 2.0,          'C', "x4"))
43
44        # Add Constraints.
45        constr = []
46        constr.append(model.addConstr(-0.5 * x[0]       + x[1]                    >= 0.5,  "c0"))
47        constr.append(model.addConstr( 2.0 * x[0]       - x[1]                    >= 3.0,  "c1"))
48        constr.append(model.addConstr( 3.0 * x[0]       + x[1]                    <= 6.0,  "c2"))
49        constr.append(model.addConstr(                          3.0 * x[3] - x[4] <= 2.0,  "c3"))
50        constr.append(model.addConstr(       x[0]                          + x[4] <= 10.0, "c4"))
51        constr.append(model.addConstr(       x[0] + 2.0 * x[1]      + x[3]        <= 14.0, "c5"))
52        constr.append(model.addConstr(       x[1] +                   x[3]        >= 1.0,  "c6"))
53
54        # Optimize the input problem.
55        model.optimize()
56
57        # Run IIS.
58        if model.status == MDO.INFEASIBLE or model.status == MDO.INF_OR_UBD:
59            print("Optimizer terminated with an primal infeasible status.")
60            print("Start to compute an Irreducible Inconsistent Subsystem (IIS).")
61            # Compute an IIS and write it to file (in ILP format).
62            model.computeIIS()
63            print("Writing IIS into file (ILP format).")
64            model.write("./test1.ilp")
65            print("Populating all bounds participate in the computed IIS.")
66            for c in constr:
67                status = c.IISConstr
68                name = c.ConstrName
69                if status == 2:
70                    print(f"The upper bound of inequality constraint [{name}] participates in the IIS.")
71                elif status == 3:
72                    print(f"The lower bound of inequality constraint [{name}] participates in the IIS.")
73                elif status == 5:
74                    print(f"[{name}] is an equality constraint, and both its lower bound and upper bound participate in the IIS.")
75            for v in x:
76                status = v.IISVar
77                name = v.VarName
78                if status == 2:
79                    print(f"The upper bound of variable [{name}] participates in the IIS.")
80                elif status == 3:
81                    print(f"The lower bound of variable [{name}] participates in the IIS.")
82                elif status == 5:
83                    print(f"[{name}] is a fixed variable, and both its lower bound and upper bound participate in the IIS.")
84    except MindoptError as e:
85        print("Received Mindopt exception.")
86        print(" - Code          : {}".format(e.code))
87        print(" - Reason        : {}".format(e.message))
88    except Exception as e:
89        print("Received other exception.")
90        print(" - Reason        : {}".format(e))
91    finally:
92        # Free up model.
93        model.dispose()