[Cbc] How to solve a small MIQP using CBC?

Jan-Willem Goossens jhmgoossens at hotmail.com
Tue Sep 17 16:24:27 EDT 2019


Dear all,

Using CBC 2.10.3, I’m trying to solve a simple MIQP (MIP with quadratic objective) using CBC, but CbcMain1 incorrectly concludes that "Linear relaxation infeasible”.
The output includes lines which look like the correct solution (-7.5) is found, but then the end result is Linear relaxation infeasible.
..
Clp0000I Optimal - objective value -7.5
Cbc0004I Integer solution of -7.5 found after 0 iterations and 0 nodes (0.00 seconds)
Cbc0001I Search completed - best objective -7.5, took 0 iterations and 0 nodes (0.00 seconds)
..
Result - Linear relaxation infeasible
..
I must be doing something wrong. The same problem without loading the quadratic part of the objective works as expected.
The code is below.  Any suggestions?
Many thanks for your help.

Regards,

Jan-Willem


                // See https://www.inverseproblem.co.nz/OPTI/index.php/Probs/MIQP
                //  min 0.5 x1^2 + x2^2 - x1x2 - 2x1 - 6x2
                //  st. x1 + x2 <= 2
                //    -x1 + 2x2 <= 2
                //     2x1 + x2 <= 3
                //      x1 >= 0, x2 >= 0
                //     x1 and x2 integer
                //
                // Linear relaxation: x1 = 0.66, x2 = 1.333  -> obj = -8.22222
                // Integer solution:  x1 = 1,    x2 = 1      -> obj = -7.5

                int numcols = 2;
                int numrows = 3;

                // The main problem
                int startA[3] = { 0, 3, 5 }; // per variable (column), the starting position of its nonzero data, plus final
                int indexA[6] = { 0, 1, 2, 0, 1, 2 }; // The constraint index number per nonzero element
                double valueA[6] = { 1.0, -1.0, 2.0, 1.0, 2.0, 1.0 }; // The nonzero elements
                double collb[2] = { 0.0, 0.0 };
                double colub[2] = { 10000.0, 10000.0 };
                double obj[2] = { -2.0, -6.0 };
                double rowlb[3] = { -10000.0, -10000.0, -10000.0 };
                double rowub[3] = { 2.0, 2.0, 3.0 };
                // Quadratic objective
                int startObj[3] = { 0, 2, 3 };
                int columnObj[3] = { 0, 1, 1 };
                double elementObj[3] = { 1.0, -1.0, 2.0 }; // diagonals get double coefs, non-diagonals normal coefs values

                OsiClpSolverInterface solver1;

                CbcModel cbcModel(solver1);
                // solver1 was cloned, so get current copy
                OsiClpSolverInterface* osiClp = dynamic_cast<::OsiClpSolverInterface*>(cbcModel.solver());
                osiClp->loadProblem(numcols, numrows, startA, indexA, valueA, collb, colub, obj, rowlb, rowub);
                osiClp->setRowName(0, "row1");
                osiClp->setRowName(1, "row2");
                osiClp->setRowName(2, "row3");
                osiClp->setColName(0, "x1");
                osiClp->setColName(1, "x2");
                osiClp->setInteger(0);
                osiClp->setInteger(1);

                // Commenting out the next two lines  gives the expected MIP solution.
                ClpSimplex* clpSimplex = osiClp->getModelPtr();
                clpSimplex->loadQuadraticObjective(numcols, startObj, columnObj, elementObj);

                CbcMain0(cbcModel);
                const char* argv[] = { "TestQuad1", "-solve", "-quit" };
                CbcMain1(3, argv, cbcModel);

bool optimal = cbcModel.isProvenOptimal(); // false
                double objValue = cbcModel.getObjValue();
                const double* sol = cbcModel.getColSolution();
                int n = cbcModel.getNumCols();
                double x1Value = sol[0];
                double x2Value = sol[1];
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://list.coin-or.org/pipermail/cbc/attachments/20190917/dbe509bd/attachment.html>


More information about the Cbc mailing list