[Osi] How to define SOS constraint
John Forrest
john.forrest at fastercoin.com
Tue May 18 03:42:30 EDT 2010
Christian,
You will probably be better off using Cbc via CbcModel rather than
OsiCbc.
I attach a modified sos.cpp which seems to work on your example. It
does give one spurious warning when it sees there are no integers but it
goes ahead and solves it - this is the output (I added a redundant
initialSolve so I could see relaxed objective value)
Coin0506I Presolve 0 (-8) rows, 0 (-8) columns and 0 (-18) elements
Clp0000I Optimal - objective value 2
Coin0511I After Postsolve, objective 2, infeasibilities - dual 0 (0),
primal 0 (0)
Clp0032I Optimal objective 2 - 0 iterations time 0.002, Presolve 0.00
Cbc3007W No integer variables - nothing to do
Cbc0016I Integer solution of 3 found by strong branching after 0
iterations and 0 nodes (0.00 seconds)
Cbc0001I Search completed - best objective 3, took 0 iterations and 0
nodes (0.00 seconds)
Cbc0032I Strong branching done 2 times (2 iterations), fathomed 1 nodes
and fixed 0 variables
Cbc0035I Maximum depth 0, 0 variables fixed on reduced cost
Problem took 0 seconds, 0 nodes with objective 3 Finished
AC_1 = 1
AC_2 = 1
BA_2 = 1
AC = 2
John Forrest
On Mon, 2010-05-17 at 18:08 +0200, Christian Schmidt wrote:
> Hi,
>
> I'd like to define a pure SOS1 constraint (without integers). From the
> code examples I've built the following model - a network flow with two
> sources A and B for products 1 and 2 resp. and one sink C. The sink
> should only be delivered from one source.
>
> The model is:
>
> min AC_1 + AC_2 + BC_1 + BC_2 + AB_1 + BA_2
> A_1: -AC_1 - AB_1 = -1
> A_2: BA_2 - AC_2 = 0
> B_1: AB_1 - BC_1 = 0
> B_2: -BC_2 - BA_2 = -1
> C_1: AC_1 + BC_1 = 1
> C_2: AC_2 + BC_2 = 1
> sAC: AC_1 + AC_2 = AC
> sBC: BC_1 + BC_2 = BC
>
> SOS
> C: AC, BC <= 1
>
> In my attached implementation the SOS constraint is simply ignored.
> What's wrong?
>
> Thanks for any ideas,
> Christian
>
>
> #include "OsiSolverInterface.hpp"
> #include "OsiCbcSolverInterface.hpp"
>
> template<typename T, int N> inline
> int count(const T (&)[N]) { return N; }
>
> int main(int argc, char* argv[])
> {
> const double inf = 1e20;
>
> // Columns
> const char* col[] = { "AC_1", "AC_2", "BC_1", "BC_2", "AB_1", "BA_2",
> "AC", "BC" };
> enum cols { AC_1, AC_2, BC_1, BC_2, AB_1, BA_2, AC, BC };
> double collb[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
> double colub[] = { inf, inf, inf, inf, inf, inf, inf, inf };
> double colobj[]= { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0 };
> const int cols = count(col);
> assert(cols == count(col) && cols == count(collb) && cols ==
> count(colub) && cols == count(colobj));
>
> // Rows
> enum rows { A_1, A_2, B_1, B_2, C_1, C_2, rAC, rBC };
> double rowlb[] = { -1.0, 0.0, 0.0, -1.0, 1.0, 1.0, 0.0, 0.0 };
> double rowub[] = { -1.0, 0.0, 0.0, -1.0, 1.0, 1.0, 0.0, 0.0 };
> const int rows = count(rowlb);
> assert(rows == count(rowlb) && rows == count(rowub));
>
> // Matrix
> int index[] = {
> A_1, C_1, rAC // AC_1
> , A_2, C_2, rAC // AC_2
> , B_1, C_1, rBC // BC_1
> , B_2, C_2, rBC // BC_2
> , A_1, B_1 // AB_1
> , B_2, A_2 // BA_2
> , rAC // AC
> , rBC // BC
> };
> double values[] = {
> -1, +1, +1
> , -1, +1, +1
> , -1, +1, +1
> , -1, +1, +1
> , -1, +1
> , -1, +1
> , -1
> , -1
> };
> int start[] = { 0, 3, 6, 9, 12, 14, 16, 17, count(index) };
> assert(count(index) == count(values) && count(index) == start[cols]);
> assert(count(start) == cols+1);
>
> OsiSolverInterface* solver = new OsiCbcSolverInterface();
> solver->loadProblem(cols, rows, start, index, values, collb, colub,
> colobj, rowlb, rowub);
>
> int index2[] = { AC, BC };
> OsiObject* sos[] = {
> new OsiSOS(solver, count(index2), index2, NULL, 1)
> };
> solver->addObjects(1, sos);
>
> solver->setObjSense(1); // minimize
> solver->branchAndBound();
> bool solved = solver->isProvenOptimal();
> if (solved) {
> const double* solution = solver->getStrictColSolution();
> const double eps = solver->getIntegerTolerance();
> for (int i = 0; i < cols; i++)
> if (fabs(solution[i]) > eps)
> std::cout << col[i] << " = " << solution[i] << std::endl;
> } // if solved
>
> return solved;
> }
>
> _______________________________________________
> Osi mailing list
> Osi at list.coin-or.org
> http://list.coin-or.org/mailman/listinfo/osi
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: sosTest.cpp
Type: text/x-c++src
Size: 3040 bytes
Desc: not available
URL: <http://list.coin-or.org/pipermail/osi/attachments/20100518/d6f2aeca/attachment.bin>
More information about the Osi
mailing list