[Osi] How to define SOS constraint

Christian Schmidt christian2.schmidt at gmx.de
Mon May 17 12:08:59 EDT 2010


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;
}




More information about the Osi mailing list