Esempio n. 1
0
void OsiSolver::printModel() {
    printf("########\nMODEL:\nVARS :\n");
    printf("V%d(%.2lf, %.2lf)", 0, col_lb[0], col_ub[0]);
    for (int i = 1; i < n_cols; i++) {
        printf(", V%d(%.2lf,%.2lf)", i, col_lb[i], col_ub[i]);
    }

    printf("\n\nObjective : Maximise(%s): ",
           (_obj_coef == -1 ? "Minimise" : "Maximise"));
    printf("%.2lf * V%d", objective[0], 0);
    for (int i = 1; i < n_cols; i++) {
        printf(" + %.2lf * V%d", objective[i], i);
    }

    printf("\n\nMatrix:\n");
    for (int i = 0; i < matrix->getNumRows(); i++) {
        CoinShallowPackedVector row = matrix->getVector(i);
        const double* elements = row.getElements();
        const int* indices = row.getIndices();
        int n = row.getNumElements();

        if (row_lb[i] == -1.0 * si->getInfinity())
            printf("-infinity <= ");
        else
            printf("%.2lf <= ", row_lb[i]);
        printf("%.2lf * V%d", elements[0], indices[0]);
        for (int j = 1; j < n; j++)
            printf(" + %.2lf * V%d", elements[j], indices[j]);
        if (row_ub[i] == si->getInfinity())
            printf(" <= infinity\n");
        else
            printf(" <= %.2lf\n", row_ub[i]);
    }
    printf("########\n");
}
Esempio n. 2
0
void OsiSolver::build_expressions() {
    // build expressions*, first element is Sum() for the objective
    // every pair after that ((1,2),(3,4)) is a le and ge over a
    // common Sum
    const double*objCoef = si->getObjCoefficients();
    const int ncols = si->getNumCols();
    const int nrows = si->getNumRows();
    const double* col_ubs = si->getColUpper();
    const double* col_lbs = si->getColLower();
    const double* row_ubs = si->getRowUpper();
    const double* row_lbs = si->getRowLower();
    const CoinPackedMatrix* mtx = si->getMatrixByRow();

    // Build objective expression.
    OsiExpArray vars;
    OsiDoubleArray coefs;
    double sum = 0;
    for (int i = 0; i < ncols; i++) {
        Osi_Expression* var;

        if (si->isContinuous(i))
            var = new Osi_DoubleVar(col_lbs[i], col_ubs[i], i);
        else
            var = new Osi_IntVar(col_lbs[i], col_ubs[i], i);
        var->varname = si->getColName(i, 255);
        vars.add(var);
        expressions.push_back(var);
        coefs.add(objCoef[i]);
        sum += objCoef[i];
    }
    /* Only return an objective if there is one! (Empty objectives were not
     * working with some solvers
     */
    if (sum != 0) {
        expressions.push_back(new Osi_Minimise(new Osi_Sum(vars, coefs, 0)));
    }

    // Build remaining expressions, expr <= upper, expr >= lower
    for (int i = 0; i < nrows; i++) {
        CoinShallowPackedVector row = mtx->getVector(i);
        if (row.getNumElements() > 0) {
            const double* elements = row.getElements();
            const int* indices = row.getIndices();
            OsiExpArray sumvars;
            OsiDoubleArray coefs;
            for (int j = 0; j < row.getNumElements(); j++) {
                sumvars.add(vars.get_item(indices[j]));
                coefs.add(elements[j]);
            }
            Osi_Sum* expr = new Osi_Sum(sumvars, coefs, 0);
            if (!(row_ubs[i] == si->getInfinity()))
                expressions.push_back(new Osi_le(expr, row_ubs[i]));
            if (!(row_lbs[i] == -1.0 * si->getInfinity()))
                expressions.push_back(new Osi_ge(expr, row_lbs[i]));
        }
    }
}
Esempio n. 3
0
/*
 * split_ranged_rows finds rows that are bounded on both sides and creates
 * two separate rows for each. This is added since OsiVol doesn't like
 * ranged rows.
 */
void OsiSolver::splitRangedRows() {
    std::vector<double> row_ubs_new;
    std::vector<double> row_lbs_new;
    CoinPackedMatrix* matrix_new = new CoinPackedMatrix(false, 0, 0);

    for (int i = 0; i < n_rows; i++) {
        double ub_coef = row_ub[i] < 0.0 ? -1.0 : 1.0;
        double lb_coef = row_lb[i] < -1.0e20 ? 1.0 : (row_lb[i] < 0.0 ? -1.0 : 1.0);
        const CoinShallowPackedVector row = matrix->getVector(i);
        const double* elements = row.getElements();
        const int* indices = row.getIndices();

        if (row_lb[i] > -1.0e20 && row_ub[i] < 1.0e20
                && row_lb[i] != row_ub[i]) {
            CoinPackedVector row_with_ub;
            CoinPackedVector row_with_lb;

            row_ubs_new.push_back(si->getInfinity());
            row_ubs_new.push_back(ub_coef * row_ub[i]);
            row_lbs_new.push_back(lb_coef * row_lb[i]);
            row_lbs_new.push_back(-1.0 * si->getInfinity());

            for (int j = 0; j < row.getNumElements(); j++) {
                row_with_ub.insert(indices[j], ub_coef * elements[j]);
                row_with_lb.insert(indices[j], lb_coef * elements[j]);
            }
            matrix_new->appendRow(row_with_ub);
            matrix_new->appendRow(row_with_lb);
        } else {
            CoinPackedVector new_row;
            row_ubs_new.push_back(ub_coef * row_ub[i]);
            row_lbs_new.push_back(lb_coef * row_lb[i]);

            double row_coef = row_ub[i] < 1.0e20 ? (row_ub[i] < 0.0 ? -1.0 : 1.0) : (row_lb[i] < 0.0 ? -1.0 : 1.0);

            for (int j = 0; j < row.getNumElements(); j++) {
                new_row.insert(indices[j], row_coef * elements[j]);
            }

            matrix_new->appendRow(new_row);
        }
    }
    n_rows = row_ubs_new.size();

    delete matrix;
    delete[] row_lb;
    delete[] row_ub;

    row_lb = new double[n_rows];
    row_ub = new double[n_rows];
    for (int i = 0; i < n_rows; i++) {
        row_lb[i] = row_lbs_new.at(i);
        row_ub[i] = row_ubs_new.at(i);
    }

    matrix = matrix_new;
}
//-------------------------------------------------------------------
// Copy
//-------------------------------------------------------------------
CoinShallowPackedVector::CoinShallowPackedVector(const CoinShallowPackedVector &x)
  : CoinPackedVectorBase()
  , indices_(x.getIndices())
  , elements_(x.getElements())
  , nElements_(x.getNumElements())
{
  CoinPackedVectorBase::copyMaxMinIndex(x);
  try {
    CoinPackedVectorBase::setTestForDuplicateIndex(x.testForDuplicateIndex());
  } catch (CoinError &e) {
    throw CoinError("duplicate index", "copy constructor",
      "CoinShallowPackedVector");
  }
}
void
CoinShallowPackedVectorUnitTest()
{
  CoinRelFltEq eq;
  int i;
  // Test default constructor
  {
    CoinShallowPackedVector r;
    assert( r.indices_==NULL );
    assert( r.elements_==NULL );
    assert( r.nElements_==0 );
  }

  // Test set and get methods
  const int ne = 4;
  int inx[ne] = { 1, 3, 4, 7 };
  double el[ne] = { 1.2, 3.4, 5.6, 7.8 };
  {
    CoinShallowPackedVector r;    
    assert( r.getNumElements()==0 );
    
    // Test setting/getting elements with int* & double* vectors
    r.setVector( ne, inx, el );
    assert( r.getNumElements()==ne );
    for ( i=0; i<ne; i++ ) {
      assert( r.getIndices()[i]  == inx[i] );
      assert( r.getElements()[i] == el[i]  );
    }
    assert ( r.getMaxIndex()==7 );
    assert ( r.getMinIndex()==1 );

    // try to clear it
    r.clear();
    assert( r.indices_==NULL );
    assert( r.elements_==NULL );
    assert( r.nElements_==0 );

    // Test setting/getting elements with indices out of order  
    const int ne2 = 5;
    int inx2[ne2] = { 2, 4, 8, 14, 3 };
    double el2[ne2] = { 2.2, 4.4, 6.6, 8.8, 3.3 };
 
    r.setVector(ne2,inx2,el2);
    
    assert( r.getNumElements()==ne2 );    
    for (i = 0; i < ne2; ++i) {
       assert( r.getIndices()[i]==inx2[i] );
       assert( r.getElements()[i]==el2[i] );
    }
    
    assert ( r.getMaxIndex()==14 );
    assert ( r.getMinIndex()==2 );
    // try to call it once more
    assert ( r.getMaxIndex()==14 );
    assert ( r.getMinIndex()==2 );

    CoinShallowPackedVector r1(ne2,inx2,el2);
    assert( r == r1 );

    // assignment operator
    r1.clear();
    r1 = r;
    assert( r == r1 );

    // assignment from packed vector
    CoinPackedVector pv1(ne2,inx2,el2);
    r1 = pv1;
    assert( r == r1 );

    // construction
    CoinShallowPackedVector r2(r1);
    assert( r2 == r );
    
    // construction from packed vector
    CoinShallowPackedVector r3(pv1);
    assert( r3 == r );

    // test duplicate indices
    {
      const int ne3 = 4;
      int inx3[ne3] = { 2, 4, 2, 3 };
      double el3[ne3] = { 2.2, 4.4, 8.8, 6.6 };
      r.setVector(ne3,inx3,el3, false);
      assert(r.testForDuplicateIndex() == false);
      bool errorThrown = false;
      try {
        r.setTestForDuplicateIndex(true);
      }
      catch (CoinError& e) {
        errorThrown = true;
      }
      assert( errorThrown );

      r.clear();
      errorThrown = false;
      try {
	 r.setVector(ne3,inx3,el3);
      }
      catch (CoinError& e) {
        errorThrown = true;
      }
      assert( errorThrown );
	 
      errorThrown = false;
      try {
	 CoinShallowPackedVector r1(ne3,inx3,el3);
      }
      catch (CoinError& e) {
	 errorThrown = true;
      }
      assert( errorThrown );
    } 
    
  } 

  // Test copy constructor and assignment operator
  {
    CoinShallowPackedVector rhs;
    {
      CoinShallowPackedVector r;
      {
        CoinShallowPackedVector rC1(r);      
        assert( 0==r.getNumElements() );
        assert( 0==rC1.getNumElements() );
        
        r.setVector( ne, inx, el ); 
        
        assert( ne==r.getNumElements() );
        assert( 0==rC1.getNumElements() ); 
      }
      
      CoinShallowPackedVector rC2(r);   
      
      assert( ne==r.getNumElements() );
      assert( ne==rC2.getNumElements() );
      
      for ( i=0; i<ne; i++ ) {
        assert( r.getIndices()[i] == rC2.getIndices()[i] );
        assert( r.getElements()[i] == rC2.getElements()[i] );
      }

      rhs=rC2;
    }
    // Test that rhs has correct values even though lhs has gone out of scope
    assert( rhs.getNumElements()==ne );
    
    for ( i=0; i<ne; i++ ) {
      assert( inx[i] == rhs.getIndices()[i] );
      assert(  el[i] == rhs.getElements()[i] );
    } 
  }

  // Test operator==
  {
    CoinShallowPackedVector v1,v2;
    assert( v1==v2 );
    assert( v2==v1 );
    assert( v1==v1 );
    assert( !(v1!=v2) );
    
    v1.setVector( ne, inx, el );
    assert ( !(v1==v2) );
    assert ( v1!=v2 );

    CoinShallowPackedVector v3(v1);
    assert( v3==v1 );
    assert( v3!=v2 );

    CoinShallowPackedVector v4(v2);
    assert( v4!=v1 );
    assert( v4==v2 );
  }

 

  {
    // Test operator[] and isExistingIndex()
    const int ne = 4;
    int inx[ne] =   {  1,   4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinShallowPackedVector r;
    assert( r[1]==0. );

    r.setVector(ne,inx,el);

    assert( r[-1]==0. );
    assert( r[ 0]==1. );
    assert( r[ 1]==10.);
    assert( r[ 2]==50.);
    assert( r[ 3]==0. );
    assert( r[ 4]==40.);
    assert( r[ 5]==0. );
    assert(  r.isExistingIndex(2) );
    assert( !r.isExistingIndex(3) );

    assert( !r.isExistingIndex(-1) );
    assert(  r.isExistingIndex(0) );
    assert( !r.isExistingIndex(3) );
    assert(  r.isExistingIndex(4) );
    assert( !r.isExistingIndex(5) );
    
    assert ( r.getMaxIndex()==4 );
    assert ( r.getMinIndex()==0 );
  }
  
  // Test that attemping to get min/max index of a 0,
  // length vector 
  {
    CoinShallowPackedVector nullVec;
    assert( nullVec.getMaxIndex() == -COIN_INT_MAX/*0*/ );
    assert( nullVec.getMinIndex() == COIN_INT_MAX/*0*/ );
  } 

  {
     // test dense vector
     const int ne = 4;
     int inx[ne] =   {  1,   4,  0,   2 };
     double el[ne] = { 10., 40., 1., 50. };
     CoinShallowPackedVector r;
     r.setVector(ne,inx,el);
     double * dense = r.denseVector(6);
     assert(dense[0] == 1.);
     assert(dense[1] == 10.);
     assert(dense[2] == 50.);
     assert(dense[3] == 0.);
     assert(dense[4] == 40.);
     assert(dense[5] == 0.);
     delete[] dense;

     // try once more
     dense = r.denseVector(7);
     assert(dense[0] == 1.);
     assert(dense[1] == 10.);
     assert(dense[2] == 50.);
     assert(dense[3] == 0.);
     assert(dense[4] == 40.);
     assert(dense[5] == 0.);
     assert(dense[6] == 0.);
     delete[] dense;
     
  }
     
     

  
#if 0
  // what happens when someone sets 
  // the number of elements to be a negative number
  {    
    const int ne = 4;
    int inx1[ne] = { 1, 3, 4, 7 };
    double el1[ne] = { 1.2, 3.4, 5.6, 7.8 };
    CoinShallowPackedVector v1;
    v1.setVector(-ne,inx1,el1);
  }
#endif

  
  // Test adding vectors
  {    
    const int ne1 = 5;
    int inx1[ne1]   = { 1,  3,  4,  7,  5  };
    double el1[ne1] = { 1., 5., 6., 2., 9. };
    const int ne2 = 4;
    int inx2[ne2] =   { 7,  4,  2,  1  };
    double el2[ne2] = { 7., 4., 2., 1. };
    CoinShallowPackedVector v1;
    v1.setVector(ne1,inx1,el1);
    CoinShallowPackedVector v2;
    v2.setVector(ne2,inx2,el2);
    CoinPackedVector r = v1 + v2;

    const int ner = 6;
    int inxr[ner] =   {    1,     2,     3,     4,     5,     7  };
    double elr[ner] = { 1.+1., 0.+2., 5.+0., 6.+4., 9.+0., 2.+7. };
    CoinPackedVector rV;
    rV.setVector(ner,inxr,elr);
    assert( rV != r );
    assert( r.isEquivalent(rV) );
    
    CoinPackedVector p1=v1+3.1415;
    for ( i=0; i<p1.getNumElements(); i++ )
      assert( eq( p1.getElements()[i], v1.getElements()[i]+3.1415) );

    CoinPackedVector p2=(-3.1415) + p1;
    assert( p2.isEquivalent(v1) );
  } 
  
  // Test subtracting vectors
  {    
    const int ne1 = 5;
    int inx1[ne1]   = { 1,  3,  4,  7,  5  };
    double el1[ne1] = { 1., 5., 6., 2., 9. };
    const int ne2 = 4;
    int inx2[ne2] =   { 7,  4,  2,  1  };
    double el2[ne2] = { 7., 4., 2., 1. };
    CoinShallowPackedVector v1;
    v1.setVector(ne1,inx1,el1);
    CoinShallowPackedVector v2;
    v2.setVector(ne2,inx2,el2);
    CoinPackedVector r = v1 - v2;

    const int ner = 6;
    int inxr[ner] =   {    1,     2,     3,     4,     5,     7  };
    double elr[ner] = { 1.-1., 0.-2., 5.-0., 6.-4., 9.-0., 2.-7. };
    CoinPackedVector rV;
    rV.setVector(ner,inxr,elr);
    assert( r.isEquivalent(rV) );  
    
    CoinPackedVector p1=v1-3.1415;
    for ( i=0; i<p1.getNumElements(); i++ )
      assert( eq( p1.getElements()[i], v1.getElements()[i]-3.1415) );
  } 
  
  // Test multiplying vectors
  {    
    const int ne1 = 5;
    int inx1[ne1]   = { 1,  3,  4,  7,  5  };
    double el1[ne1] = { 1., 5., 6., 2., 9. };
    const int ne2 = 4;
    int inx2[ne2] =   { 7,  4,  2,  1  };
    double el2[ne2] = { 7., 4., 2., 1. };
    CoinShallowPackedVector v1;
    v1.setVector(ne1,inx1,el1);
    CoinShallowPackedVector v2;
    v2.setVector(ne2,inx2,el2);
    CoinPackedVector r = v1 * v2;

    const int ner = 6;
    int inxr[ner] =   {    1,     2,     3,     4,     5,     7  };
    double elr[ner] = { 1.*1., 0.*2., 5.*0., 6.*4., 9.*0., 2.*7. };
    CoinPackedVector rV;
    rV.setVector(ner,inxr,elr);
    assert( r.isEquivalent(rV) );

    CoinPackedVector p1=v1*3.3;
    for ( i=0; i<p1.getNumElements(); i++ )
      assert( eq( p1.getElements()[i], v1.getElements()[i]*3.3) );
    
    CoinPackedVector p2=(1./3.3) * p1;
    assert( p2.isEquivalent(v1) );
  } 
  
  // Test dividing vectors
  {    
    const int ne1 = 3;
    int inx1[ne1]   = { 1,  4,  7  };
    double el1[ne1] = { 1., 6., 2. };
    const int ne2 = 4;
    int inx2[ne2] =   { 7,  4,  2,  1  };
    double el2[ne2] = { 7., 4., 2., 1. };
    CoinShallowPackedVector v1;
    v1.setVector(ne1,inx1,el1);
    CoinShallowPackedVector v2;
    v2.setVector(ne2,inx2,el2);
    CoinPackedVector r = v1 / v2;

    const int ner = 4;
    int inxr[ner] =   {    1,     2,      4,     7  };
    double elr[ner] = { 1./1., 0./2.,  6./4., 2./7. };
    CoinPackedVector rV;
    rV.setVector(ner,inxr,elr);
    assert( r.isEquivalent(rV) );
        
    CoinPackedVector p1=v1/3.1415;
    for ( i=0; i<p1.getNumElements(); i++ )
      assert( eq( p1.getElements()[i], v1.getElements()[i]/3.1415) );
  }
   
  // Test sum
  { 
    CoinShallowPackedVector s;
    assert( s.sum() == 0 );

    int inx = 25;
    double value = 45.;
    s.setVector(1, &inx, &value);
    assert(s.sum()==45.);

    const int ne1 = 5;
    int inx1[ne1]   = { 10,  3,  4,  7,  5  };
    double el1[ne1] = { 1., 5., 6., 2., 9. };
    s.setVector(ne1,inx1,el1);

    assert(s.sum()==1.+5.+6.+2.+9.);
  }
  
  // Just another interesting test
  {    
    // Create numerator vector
    const int ne1 = 2;
    int inx1[ne1]   = { 1,  4  };
    double el1[ne1] = { 1., 6. };
    CoinShallowPackedVector v1(ne1,inx1,el1);

    // create denominator vector
    const int ne2 = 3;
    int inx2[ne2] =   { 1,  2,  4 };
    double el2[ne2] = { 1., 7., 4.};
    CoinShallowPackedVector v2(ne2,inx2,el2);

    // Compute ratio
    CoinPackedVector ratio = v1 / v2;

    // Sort ratios
    ratio.sortIncrElement();

    // Test that the sort really worked
    assert( ratio.getElements()[0] == 0.0/7.0 );
    assert( ratio.getElements()[1] == 1.0/1.0 );
    assert( ratio.getElements()[2] == 6.0/4.0 );

    // Get numerator of of sorted ratio vector
    assert( v1[ ratio.getIndices()[0] ] == 0.0 );
    assert( v1[ ratio.getIndices()[1] ] == 1.0 );
    assert( v1[ ratio.getIndices()[2] ] == 6.0 );

    // Get denominator of of sorted ratio vector
    assert( v2[ ratio.getIndices()[0] ] == 7.0 );
    assert( v2[ ratio.getIndices()[1] ] == 1.0 );
    assert( v2[ ratio.getIndices()[2] ] == 4.0 );
  }

  {
    // Test that sample usage works

    const int ne = 4;
    int inx[ne] =   {  1,   4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinShallowPackedVector r(ne,inx,el);

    assert( r.getIndices()[0]== 1  );
    assert( r.getElements()[0]==10. );
    assert( r.getIndices()[1]== 4  );
    assert( r.getElements()[1]==40. );
    assert( r.getIndices()[2]== 0  );
    assert( r.getElements()[2]== 1. );
    assert( r.getIndices()[3]== 2  );
    assert( r.getElements()[3]==50. );

    assert( r[ 0]==1. );
    assert( r[ 1]==10.);
    assert( r[ 2]==50.);
    assert( r[ 3]==0. );
    assert( r[ 4]==40.);

    CoinShallowPackedVector r1;
    r1=r;
    assert( r==r1 );

    CoinPackedVector add = r + r1;
    assert( add[0] ==  1.+ 1. );
    assert( add[1] == 10.+10. );
    assert( add[2] == 50.+50. );
    assert( add[3] ==  0.+ 0. );
    assert( add[4] == 40.+40. );

    assert( r.sum() == 10.+40.+1.+50. );
  }
  
  {
    // Test findIndex
    const int ne = 4;
    int inx[ne] =   {  1,  -4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinShallowPackedVector r(ne,inx,el);

    assert( r.findIndex(2)  == 3 );
    assert( r.findIndex(0)  == 2 );
    assert( r.findIndex(-4) == 1 );
    assert( r.findIndex(1)  == 0 );
    assert( r.findIndex(3)  == -1 );
  }  
  {
    // Test construction with testing for duplicates as false
    const int ne = 4;
    int inx[ne] =   {  1,  -4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinShallowPackedVector r(ne,inx,el,false);

    assert( r.isExistingIndex(1) );
    assert( r.isExistingIndex(-4) );
    assert( r.isExistingIndex(0) );
    assert( r.isExistingIndex(2) );
    assert( !r.isExistingIndex(3) );
    assert( !r.isExistingIndex(-3) );
  }
}