void OsiColCut::setUbs( int size, const int * colIndices, const double * ubElements ) { ubs_.setVector(size,colIndices,ubElements); }
void OsiIF::_addCols(ArrayBuffer<Column*> &newCols) { CoinPackedVector *newcol = new CoinPackedVector; for (int i = 0; i < newCols.size(); i++) { int num = newCols[i]->nnz(); double ub = newCols[i]->uBound(); double lb = newCols[i]->lBound(); double obj = newCols[i]->obj(); int *supports = new int[num]; //!< supports of added rows double *coeffs = new double[num]; //!< coefficients of added rows for (int j = 0; j < num; j++) { supports[j] = newCols[i]->support(j); coeffs[j] = newCols[i]->coeff(j); } newcol->setVector(num, supports, coeffs); lpSolverTime_.start(); osiLP_->addCol(*newcol, lb, ub, obj); lpSolverTime_.stop(); freeInt(supports); freeDouble(coeffs); } lpSolverTime_.start(); numCols_ = osiLP_->getNumCols(); collower_ = osiLP_->getColLower(); colupper_ = osiLP_->getColUpper(); objcoeff_ = osiLP_->getObjCoefficients(); lpSolverTime_.stop(); delete newcol; }
//------------------------------------------------------------------- // Set lower & upper bound vectors //------------------------------------------------------------------- void OsiColCut::setLbs( int size, const int * colIndices, const double * lbElements ) { lbs_.setVector(size,colIndices,lbElements); }
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) ); } }
//-------------------------------------------------------------------------- // test EKKsolution methods. void CglOddHoleUnitTest( const OsiSolverInterface * baseSiP, const std::string mpsDir ) { CoinRelFltEq eq(0.000001); // Test default constructor { CglOddHole aGenerator; } // Test copy & assignment { CglOddHole rhs; { CglOddHole bGenerator; CglOddHole cGenerator(bGenerator); rhs=bGenerator; } } // test on simple case { const int nRows=3; const int nCols=3; const int nEls=6; const double elem[]={1.0,1.0,1.0,1.0,1.0,1.0}; const int row[]={0,1,0,2,1,2}; const CoinBigIndex start[]={0,2,4}; const int len[]={2,2,2}; CoinPackedMatrix matrix(true,nRows,nCols,nEls,elem,row,start,len); const double sol[]={0.5,0.5,0.5}; const double dj[]={0,0,0}; const int which[]={1,1,1}; const int fixed[]={0,0,0}; OsiCuts cs; CglOddHole test1; CglTreeInfo info; info.randomNumberGenerator=NULL; test1.generateCuts(NULL,matrix,sol,dj,cs,which,fixed,info,true); CoinPackedVector check; int index[] = {0,1,2}; double el[] = {1,1,1}; check.setVector(3,index,el); //assert (cs.sizeRowCuts()==2); assert (cs.sizeRowCuts()==1); // sort Elements in increasing order CoinPackedVector rpv=cs.rowCut(0).row(); rpv.sortIncrIndex(); assert (check==rpv); } // Testcase /u/rlh/osl2/mps/scOneInt.mps // Model has 3 continous, 2 binary, and 1 general // integer variable. { OsiSolverInterface * siP = baseSiP->clone(); std::string fn = mpsDir+"scOneInt"; siP->readMps(fn.c_str(),"mps"); #if 0 CglOddHole cg; int nCols=siP->getNumCols(); // Test the siP methods for detecting // variable type int numCont=0, numBinary=0, numIntNonBinary=0, numInt=0; for (int thisCol=0; thisCol<nCols; thisCol++) { if ( siP->isContinuous(thisCol) ) numCont++; if ( siP->isBinary(thisCol) ) numBinary++; if ( siP->isIntegerNonBinary(thisCol) ) numIntNonBinary++; if ( siP->isInteger(thisCol) ) numInt++; } assert(numCont==3); assert(numBinary==2); assert(numIntNonBinary==1); assert(numInt==3); // Test initializeCutGenerator siP->initialSolve(); assert(xstar !=NULL); for (i=0; i<nCols; i++){ assert(complement[i]==0); } int nRows=siP->getNumRows(); for (i=0; i<nRows; i++){ int vectorsize = siP->getMatrixByRow()->getVectorSize(i); assert(vectorsize==2); } kccg.cleanUpCutGenerator(complement,xstar); #endif delete siP; } }
//-------------------------------------------------------------------------- // test EKKsolution methods. void CglProbingUnitTest( const OsiSolverInterface * baseSiP, const std::string mpsDir ) { # ifdef CGL_DEBUG int i ; // define just once # endif CoinRelFltEq eq(0.000001); // Test default constructor { CglProbing aGenerator; } // Test copy & assignment { CglProbing rhs; { CglProbing bGenerator; CglProbing cGenerator(bGenerator); rhs=bGenerator; } } { OsiCuts osicuts; CglProbing test1; OsiSolverInterface * siP = baseSiP->clone(); int nColCuts; int nRowCuts; std::string fn = mpsDir+"p0033"; siP->readMps(fn.c_str(),"mps"); siP->initialSolve(); // just unsatisfied variables test1.generateCuts(*siP,osicuts); nColCuts = osicuts.sizeColCuts(); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" probing cuts"<<std::endl; { std::cout<<"there are "<<nColCuts<<" probing column cuts"<<std::endl; #ifdef CGL_DEBUG const double * lo = siP->getColLower(); const double * up = siP->getColUpper(); for (i=0; i<nColCuts; i++){ OsiColCut ccut; CoinPackedVector cpv; ccut = osicuts.colCut(i); cpv = ccut.lbs(); int n = cpv.getNumElements(); int j; const int * indices = cpv.getIndices(); double* elements = cpv.getElements(); for (j=0;j<n;j++) { int icol=indices[j]; if (elements[j]>lo[icol]) std::cout<<"Can increase lb on "<<icol<<" from "<<lo[icol]<< " to "<<elements[j]<<std::endl; } cpv = ccut.ubs(); n = cpv.getNumElements(); indices = cpv.getIndices(); elements = cpv.getElements(); for (j=0;j<n;j++) { int icol=indices[j]; if (elements[j]<up[icol]) std::cout<<"Can decrease ub on "<<icol<<" from "<<up[icol]<< " to "<<elements[j]<<std::endl; } } #endif } #ifdef CGL_DEBUG for (i=0; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; const double * colsol = siP->getColSolution(); rcut = osicuts.rowCut(i); rpv = rcut.row(); const int n = rpv.getNumElements(); const int * indices = rpv.getIndices(); double* elements = rpv.getElements(); double sum2=0.0; int k=0; double lb=rcut.lb(); double ub=rcut.ub(); for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) { std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl; for (k=0; k<n; k++){ int column=indices[k]; std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<< colsol[column]<<") "; } std::cout <<std::endl; } } #endif if (nRowCuts==1) { CoinPackedVector check; int index[] = {6,32}; double el[] = {1,1}; check.setVector(2,index,el); // sort Elements in increasing order CoinPackedVector rpv=osicuts.rowCut(0).row(); assert (rpv.getNumElements()==2); rpv.sortIncrIndex(); assert (check==rpv); assert (osicuts.rowCut(0).lb()==1.0); } // now all variables osicuts=OsiCuts(); test1.setMode(2); test1.setRowCuts(3); test1.generateCuts(*siP,osicuts); nColCuts = osicuts.sizeColCuts(); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" probing cuts"<<std::endl; { std::cout<<"there are "<<nColCuts<<" probing column cuts"<<std::endl; #ifdef CGL_DEBUG const double * lo = siP->getColLower(); const double * up = siP->getColUpper(); for (i=0; i<nColCuts; i++){ OsiColCut ccut; CoinPackedVector cpv; ccut = osicuts.colCut(i); cpv = ccut.lbs(); int n = cpv.getNumElements(); int j; const int * indices = cpv.getIndices(); double* elements = cpv.getElements(); for (j=0;j<n;j++) { int icol=indices[j]; if (elements[j]>lo[icol]) std::cout<<"Can increase lb on "<<icol<<" from "<<lo[icol]<< " to "<<elements[j]<<std::endl; } cpv = ccut.ubs(); n = cpv.getNumElements(); indices = cpv.getIndices(); elements = cpv.getElements(); for (j=0;j<n;j++) { int icol=indices[j]; if (elements[j]<up[icol]) std::cout<<"Can decrease ub on "<<icol<<" from "<<up[icol]<< " to "<<elements[j]<<std::endl; } } #endif } #ifdef CGL_DEBUG for (i=0; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; const double * colsol = siP->getColSolution(); rcut = osicuts.rowCut(i); rpv = rcut.row(); const int n = rpv.getNumElements(); const int * indices = rpv.getIndices(); double* elements = rpv.getElements(); double sum2=0.0; int k=0; double lb=rcut.lb(); double ub=rcut.ub(); for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) { std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl; for (k=0; k<n; k++){ int column=indices[k]; std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<< colsol[column]<<") "; } std::cout <<std::endl; } } #endif assert (osicuts.sizeRowCuts()>=4); delete siP; } }
//------------------------------------------------------------------- // Set row elements //------------------------------------------------------------------- void OsiRowCut::setRow(int size, const int * colIndices, const double * elements) { row_.setVector(size,colIndices,elements); }
//-------------------------------------------------------------------------- void CglKnapsackCoverUnitTest( const OsiSolverInterface * baseSiP, const std::string mpsDir ) { int i; CoinRelFltEq eq(0.000001); // Test default constructor { CglKnapsackCover kccGenerator; } // Test copy & assignment { CglKnapsackCover rhs; { CglKnapsackCover kccGenerator; CglKnapsackCover cgC(kccGenerator); rhs=kccGenerator; } } // test exactSolveKnapsack { CglKnapsackCover kccg; const int n=7; double c=50; double p[n] = {70,20,39,37,7,5,10}; double w[n] = {31, 10, 20, 19, 4, 3, 6}; double z; int x[n]; int exactsol = kccg.exactSolveKnapsack(n, c, p, w, z, x); assert(exactsol==1); assert (z == 107); assert (x[0]==1); assert (x[1]==0); assert (x[2]==0); assert (x[3]==1); assert (x[4]==0); assert (x[5]==0); assert (x[6]==0); } /* // Testcase /u/rlh/osl2/mps/scOneInt.mps // Model has 3 continous, 2 binary, and 1 general // integer variable. { OsiSolverInterface * siP = baseSiP->clone(); int * complement=NULL; double * xstar=NULL; siP->readMps("../Mps/scOneInt","mps"); CglKnapsackCover kccg; int nCols=siP->getNumCols(); // Test the siP methods for detecting // variable type int numCont=0, numBinary=0, numIntNonBinary=0, numInt=0; for (int thisCol=0; thisCol<nCols; thisCol++) { if ( siP->isContinuous(thisCol) ) numCont++; if ( siP->isBinary(thisCol) ) numBinary++; if ( siP->isIntegerNonBinary(thisCol) ) numIntNonBinary++; if ( siP->isInteger(thisCol) ) numInt++; } assert(numCont==3); assert(numBinary==2); assert(numIntNonBinary==1); assert(numInt==3); // Test initializeCutGenerator siP->initialSolve(); assert(xstar !=NULL); for (i=0; i<nCols; i++){ assert(complement[i]==0); } int nRows=siP->getNumRows(); for (i=0; i<nRows; i++){ int vectorsize = siP->getMatrixByRow()->vectorSize(i); assert(vectorsize==2); } kccg.cleanUpCutGenerator(complement,xstar); delete siP; } */ // Testcase /u/rlh/osl2/mps/tp3.mps // Models has 3 cols, 3 rows // Row 0 yields a knapsack, others do not. { // setup OsiSolverInterface * siP = baseSiP->clone(); std::string fn(mpsDir+"tp3"); siP->readMps(fn.c_str(),"mps"); // All integer variables should be binary. // Assert that this is true. for ( i = 0; i < siP->getNumCols(); i++ ) if ( siP->isInteger(i) ) assert(siP->getColUpper()[i]==1.0 && siP->isBinary(i)); OsiCuts cs; CoinPackedVector krow; double b=0; int nCols=siP->getNumCols(); int * complement=new int [nCols]; double * xstar=new double [nCols]; CglKnapsackCover kccg; // solve LP relaxation // a "must" before calling initialization siP->initialSolve(); double lpRelaxBefore=siP->getObjValue(); std::cout<<"Initial LP value: "<<lpRelaxBefore<<std::endl; assert( eq(siP->getObjValue(), 97.185) ); double mycs[] = {.627, .667558333333, .038}; siP->setColSolution(mycs); const double *colsol = siP->getColSolution(); int k; for (k=0; k<nCols; k++){ xstar[k]=colsol[k]; complement[k]=0; } // test deriveAKnapsack int rind = ( siP->getRowSense()[0] == 'N' ) ? 1 : 0; const CoinShallowPackedVector reqdBySunCC = siP->getMatrixByRow()->getVector(rind) ; int deriveaknap = kccg.deriveAKnapsack(*siP, cs, krow,b,complement,xstar,rind,reqdBySunCC); assert(deriveaknap ==1); assert(complement[0]==0); assert(complement[1]==1); assert(complement[2]==1); int inx[3] = {0,1,2}; double el[3] = {161, 120, 68}; CoinPackedVector r; r.setVector(3,inx,el); assert (krow == r); //assert (b == 183.0); ????? but x1 and x2 at 1 is valid // test findGreedyCover CoinPackedVector cover,remainder; #if 0 int findgreedy = kccg.findGreedyCover( 0, krow, b, xstar, cover, remainder ); assert( findgreedy == 1 ); int coveri = cover.getNumElements(); assert( cover.getNumElements() == 2); coveri = cover.getIndices()[0]; assert( cover.getIndices()[0] == 0); assert( cover.getIndices()[1] == 1); assert( cover.getElements()[0] == 161.0); assert( cover.getElements()[1] == 120.0); assert( remainder.getNumElements() == 1); assert( remainder.getIndices()[0] == 2); assert( remainder.getElements()[0] == 68.0); // test liftCoverCut CoinPackedVector cut; double * rowupper = ekk_rowupper(model); double cutRhs = cover.getNumElements() - 1.0; kccg.liftCoverCut(b, krow.getNumElements(), cover, remainder, cut); assert ( cut.getNumElements() == 3 ); assert ( cut.getIndices()[0] == 0 ); assert ( cut.getIndices()[1] == 1 ); assert ( cut.getIndices()[2] == 2 ); assert( cut.getElements()[0] == 1 ); assert( cut.getElements()[1] == 1 ); assert( eq(cut.getElements()[2], 0.087719) ); // test liftAndUncomplementAndAdd OsiCuts cuts; kccg.liftAndUncomplementAndAdd(*siP.getRowUpper()[0],krow,b,complement,0, cover,remainder,cuts); int sizerowcuts = cuts.sizeRowCuts(); assert ( sizerowcuts== 1 ); OsiRowCut testRowCut = cuts.rowCut(0); CoinPackedVector testRowPV = testRowCut.row(); OsiRowCut sampleRowCut; const int sampleSize = 3; int sampleCols[sampleSize]={0,1,2}; double sampleElems[sampleSize]={1.0,-1.0,-0.087719}; sampleRowCut.setRow(sampleSize,sampleCols,sampleElems); sampleRowCut.setLb(-DBL_MAX); sampleRowCut.setUb(-0.087719); bool equiv = testRowPV.equivalent(sampleRowCut.row(),CoinRelFltEq(1.0e-05) ); assert ( equiv ); #endif // test find PseudoJohnAndEllisCover cover.setVector(0,NULL, NULL); remainder.setVector(0,NULL,NULL); rind = ( siP->getRowSense()[0] == 'N' ) ? 1 : 0; int findPJE = kccg.findPseudoJohnAndEllisCover( rind, krow, b, xstar, cover, remainder ); assert( findPJE == 1 ); assert ( cover.getIndices()[0] == 0 ); assert ( cover.getIndices()[1] == 2 ); assert ( cover.getElements()[0] == 161 ); assert ( cover.getElements()[1] == 68 ); assert ( remainder.getIndices()[0] == 1 ); assert ( remainder.getElements()[0] == 120 ); OsiCuts cuts; kccg.liftAndUncomplementAndAdd((*siP).getRowUpper()[rind],krow,b, complement, rind, cover,remainder,cuts); assert (cuts.sizeRowCuts() == 1 ); OsiRowCut testRowCut = cuts.rowCut(0); CoinPackedVector testRowPV = testRowCut.row(); const int sampleSize = 3; int sampleCols[sampleSize]={0,1,2}; double sampleElems[sampleSize]={1.0, -1.0, -1.0}; OsiRowCut sampleRowCut; sampleRowCut.setRow(sampleSize,sampleCols,sampleElems); sampleRowCut.setLb(-COIN_DBL_MAX); sampleRowCut.setUb(-1.0); // test for 'close enough' assert( testRowPV.isEquivalent(sampleRowCut.row(),CoinRelFltEq(1.0e-05) ) ); // Reset complement & test next row for (i=0; i<nCols; i++){ complement[i]=0; } rind++; const CoinShallowPackedVector reqdBySunCC2 = siP->getMatrixByRow()->getVector(rind) ; deriveaknap = kccg.deriveAKnapsack(*siP,cuts,krow,b,complement,xstar,rind,reqdBySunCC2); assert(deriveaknap==0); // Reset complement & test next row for (i=0; i<nCols; i++){ complement[i]=0; } const CoinShallowPackedVector reqdBySunCC3 = siP->getMatrixByRow()->getVector(2) ; deriveaknap = kccg.deriveAKnapsack(*siP,cuts,krow,b,complement,xstar,2, reqdBySunCC3); assert(deriveaknap == 0); // Clean up delete [] complement; delete [] xstar; delete siP; } #if 0 // Testcase /u/rlh/osl2/mps/tp4.mps // Models has 6 cols, 1 knapsack row and // 3 rows explicily bounding variables // Row 0 yields a knapsack cover cut // using findGreedyCover which moves the // LP objective function value. { // Setup EKKContext * env=ekk_initializeContext(); EKKModel * model = ekk_newModel(env,""); OsiSolverInterface si(model); ekk_importModel(model, "tp4.mps"); CglKnapsackCover kccg; kccg.ekk_validateIntType(si); // Solve the LP relaxation of the model and // print out ofv for sake of comparison ekk_allSlackBasis(model); ekk_crash(model,1); ekk_primalSimplex(model,1); double lpRelaxBefore=ekk_getRobjvalue(model); #ifdef CGL_DEBUG printf("\n\nOrig LP min=%f\n",lpRelaxBefore); #endif // Determine if lp sol is ip optimal // Note: no ekk_function to do this int nCols=ekk_getInumcols(model); double * optLpSol = ekk_colsol(model); int ipOpt = 1; i=0; while (i++<nCols && ipOpt){ if(optLpSol[i] < 1.0-1.0e-08 && optLpSol[i]> 1.0e-08) ipOpt = 0; } if (ipOpt){ #ifdef CGL_DEBUG printf("Lp solution is within ip optimality tolerance\n"); #endif } else { OsiSolverInterface iModel(model); OsiCuts cuts; // Test generateCuts method kccg.generateCuts(iModel,cuts); OsiSolverInterface::ApplyCutsReturnCode rc = iModel.applyCuts(cuts); ekk_mergeBlocks(model,1); ekk_dualSimplex(model); double lpRelaxAfter=ekk_getRobjvalue(model); #ifdef CGL_DEBUG printf("\n\nFinal LP min=%f\n",lpRelaxAfter); #endif assert( lpRelaxBefore < lpRelaxAfter ); // This may need to be updated as other // minimal cover finders are added assert( cuts.sizeRowCuts() == 1 ); OsiRowCut testRowCut = cuts.rowCut(0); CoinPackedVector testRowPV = testRowCut.row(); OsiRowCut sampleRowCut; const int sampleSize = 6; int sampleCols[sampleSize]={0,1,2,3,4,5}; double sampleElems[sampleSize]={1.0,1.0,1.0,1.0,0.5, 2.0}; sampleRowCut.setRow(sampleSize,sampleCols,sampleElems); sampleRowCut.setLb(-DBL_MAX); sampleRowCut.setUb(3.0); bool equiv = testRowPV.equivalent(sampleRowCut.row(),CoinRelFltEq(1.0e-05) ); assert( testRowPV.equivalent(sampleRowCut.row(),CoinRelFltEq(1.0e-05) ) ); } // Exit out of OSL ekk_deleteModel(model); ekk_endContext(env); } #endif // Testcase /u/rlh/osl2/mps/tp5.mps // Models has 6 cols, 1 knapsack row and // 3 rows explicily bounding variables // Row 0 yields a knapsack cover cut // using findGreedyCover which moves the // LP objective function value. { // Setup OsiSolverInterface * siP = baseSiP->clone(); std::string fn(mpsDir+"tp5"); siP->readMps(fn.c_str(),"mps"); // All integer variables should be binary. // Assert that this is true. for ( i = 0; i < siP->getNumCols(); i++ ) if ( siP->isInteger(i) ) assert(siP->getColUpper()[i]==1.0 && siP->isBinary(i)); CglKnapsackCover kccg; // Solve the LP relaxation of the model and // print out ofv for sake of comparison siP->initialSolve(); double lpRelaxBefore=siP->getObjValue(); assert( eq(lpRelaxBefore, -51.66666666667) ); double mycs[] = {.8999999999, .899999999999, .89999999999, 1.110223e-16, .5166666666667, 0}; siP->setColSolution(mycs); #ifdef CGL_DEBUG printf("\n\nOrig LP min=%f\n",lpRelaxBefore); #endif // Determine if lp sol is 0/1 optimal int nCols=siP->getNumCols(); const double * optLpSol = siP->getColSolution(); bool ipOpt = true; i=0; while (i++<nCols && ipOpt){ if(optLpSol[i] > kccg.epsilon_ && optLpSol[i] < kccg.onetol_) ipOpt = false; } if (ipOpt){ #ifdef CGL_DEBUG printf("Lp solution is within ip optimality tolerance\n"); #endif } else { // set up OsiCuts cuts; CoinPackedVector krow; double b=0.0; int * complement=new int[nCols]; double * xstar=new double[nCols]; // initialize cut generator const double *colsol = siP->getColSolution(); for (i=0; i<nCols; i++){ xstar[i]=colsol[i]; complement[i]=0; } int row = ( siP->getRowSense()[0] == 'N' ) ? 1 : 0; // transform row into canonical knapsack form const CoinShallowPackedVector reqdBySunCC = siP->getMatrixByRow()->getVector(row) ; if (kccg.deriveAKnapsack(*siP, cuts, krow, b, complement, xstar, row,reqdBySunCC)){ CoinPackedVector cover, remainder; // apply greedy logic to detect violated minimal cover inequalities if (kccg.findGreedyCover(row, krow, b, xstar, cover, remainder) == 1){ // lift, uncomplements, and add cut to cut set kccg.liftAndUncomplementAndAdd((*siP).getRowUpper()[row],krow, b, complement, row, cover, remainder, cuts); } // reset optimal column solution (xstar) information in OSL const double * rowupper = siP->getRowUpper(); int k; if (fabs(b-rowupper[row]) > 1.0e-05) { for(k=0; k<krow.getNumElements(); k++) { if (complement[krow.getIndices()[k]]){ xstar[krow.getIndices()[k]]= 1.0-xstar[krow.getIndices()[k]]; complement[krow.getIndices()[k]]=0; } } } // clean up delete [] complement; delete [] xstar; } // apply the cuts OsiSolverInterface::ApplyCutsReturnCode rc = siP->applyCuts(cuts); siP->resolve(); double lpRelaxAfter=siP->getObjValue(); assert( eq(lpRelaxAfter, -30.0) ); #ifdef CGL_DEBUG printf("\n\nFinal LP min=%f\n",lpRelaxAfter); #endif // test that expected cut was detected assert( lpRelaxBefore < lpRelaxAfter ); assert( cuts.sizeRowCuts() == 1 ); OsiRowCut testRowCut = cuts.rowCut(0); CoinPackedVector testRowPV = testRowCut.row(); OsiRowCut sampleRowCut; const int sampleSize = 6; int sampleCols[sampleSize]={0,1,2,3,4,5}; double sampleElems[sampleSize]={1.0,1.0,1.0,0.25,1.0,2.0}; sampleRowCut.setRow(sampleSize,sampleCols,sampleElems); sampleRowCut.setLb(-COIN_DBL_MAX); sampleRowCut.setUb(3.0); assert(testRowPV.isEquivalent(sampleRowCut.row(),CoinRelFltEq(1.0e-05))); } delete siP; } // Testcase /u/rlh/osl2/mps/p0033 // Miplib3 problem p0033 // Test that no cuts chop off the optimal solution { // Setup OsiSolverInterface * siP = baseSiP->clone(); std::string fn(mpsDir+"p0033"); siP->readMps(fn.c_str(),"mps"); // All integer variables should be binary. // Assert that this is true. for ( i = 0; i < siP->getNumCols(); i++ ) if ( siP->isInteger(i) ) assert(siP->getColUpper()[i]==1.0 && siP->isBinary(i)); int nCols=siP->getNumCols(); CglKnapsackCover kccg; // Solve the LP relaxation of the model and // print out ofv for sake of comparison siP->initialSolve(); double lpRelaxBefore=siP->getObjValue(); assert( eq(lpRelaxBefore, 2520.5717391304347) ); double mycs[] = {0, 1, 0, 0, -2.0837010502455788e-19, 1, 0, 0, 1, 0.021739130434782594, 0.35652173913043478, -6.7220534694101275e-18, 5.3125906451789717e-18, 1, 0, 1.9298798670241979e-17, 0, 0, 0, 7.8875708048320448e-18, 0.5, 0, 0.85999999999999999, 1, 1, 0.57999999999999996, 1, 0, 1, 0, 0.25, 0, 0.67500000000000004}; siP->setColSolution(mycs); #ifdef CGL_DEBUG printf("\n\nOrig LP min=%f\n",lpRelaxBefore); #endif OsiCuts cuts; // Test generateCuts method kccg.generateCuts(*siP,cuts); OsiSolverInterface::ApplyCutsReturnCode rc = siP->applyCuts(cuts); siP->resolve(); double lpRelaxAfter=siP->getObjValue(); assert( eq(lpRelaxAfter, 2829.0597826086955) ); #ifdef CGL_DEBUG printf("\n\nOrig LP min=%f\n",lpRelaxBefore); printf("\n\nFinal LP min=%f\n",lpRelaxAfter); #endif assert( lpRelaxBefore < lpRelaxAfter ); // the CoinPackedVector p0033 is the optimal // IP solution to the miplib problem p0033 int objIndices[14] = { 0, 6, 7, 9, 13, 17, 18, 22, 24, 25, 26, 27, 28, 29 }; CoinPackedVector p0033(14,objIndices,1.0); // Sanity check const double * objective=siP->getObjCoefficients(); double ofv =0 ; int r; for (r=0; r<nCols; r++){ ofv=ofv + p0033[r]*objective[r]; } CoinRelFltEq eq; assert( eq(ofv,3089.0) ); int nRowCuts = cuts.sizeRowCuts(); OsiRowCut rcut; CoinPackedVector rpv; for (i=0; i<nRowCuts; i++){ rcut = cuts.rowCut(i); rpv = rcut.row(); double p0033Sum = (rpv*p0033).sum(); assert (p0033Sum <= rcut.ub() ); } delete siP; } // if a debug file is there then look at it { FILE * fp = fopen("knapsack.debug","r"); if (fp) { int ncol,nel; double up; int x = fscanf(fp,"%d %d %lg",&ncol,&nel,&up); if (x<=0) throw("bad fscanf"); printf("%d columns, %d elements, upper %g\n",ncol,nel,up); double * sol1 = new double[nel]; double * el1 = new double[nel]; int * col1 = new int[nel]; CoinBigIndex * start = new CoinBigIndex [ncol+1]; memset(start,0,ncol*sizeof(CoinBigIndex )); int * row = new int[nel]; int i; for (i=0;i<nel;i++) { x=fscanf(fp,"%d %lg %lg",col1+i,el1+i,sol1+i); if (x<=0) throw("bad fscanf"); printf("[%d, e=%g, v=%g] ",col1[i],el1[i],sol1[i]); start[col1[i]]=1; row[i]=0; } printf("\n"); // Setup OsiSolverInterface * siP = baseSiP->clone(); double lo=-1.0e30; double * upper = new double[ncol]; start[ncol]=nel; int last=0; for (i=0;i<ncol;i++) { upper[i]=1.0; int marked=start[i]; start[i]=last; if (marked) last++; } siP->loadProblem(ncol,1,start,row,el1,NULL,upper,NULL,&lo,&up); // use upper for solution memset(upper,0,ncol*sizeof(double)); for (i=0;i<nel;i++) { int icol=col1[i]; upper[icol]=sol1[i]; siP->setInteger(icol); } siP->setColSolution(upper); delete [] sol1; delete [] el1; delete [] col1; delete [] start; delete [] row; delete [] upper; CglKnapsackCover kccg; OsiCuts cuts; // Test generateCuts method kccg.generateCuts(*siP,cuts); // print out and compare to known cuts int numberCuts = cuts.sizeRowCuts(); if (numberCuts) { for (i=0;i<numberCuts;i++) { OsiRowCut * thisCut = cuts.rowCutPtr(i); int n=thisCut->row().getNumElements(); printf("Cut %d has %d entries, rhs %g %g =>",i,n,thisCut->lb(), thisCut->ub()); int j; const int * index = thisCut->row().getIndices(); const double * element = thisCut->row().getElements(); for (j=0;j<n;j++) { printf(" (%d,%g)",index[j],element[j]); } printf("\n"); } } fclose(fp); } } // Testcase /u/rlh/osl2/mps/p0201 // Miplib3 problem p0282 // Test that no cuts chop off the optimal ip solution { // Setup OsiSolverInterface * siP = baseSiP->clone(); std::string fn(mpsDir+"p0201"); siP->readMps(fn.c_str(),"mps"); // All integer variables should be binary. // Assert that this is true. for ( i = 0; i < siP->getNumCols(); i++ ) if ( siP->isInteger(i) ) assert(siP->getColUpper()[i]==1.0 && siP->isBinary(i)); const int nCols=siP->getNumCols(); CglKnapsackCover kccg; // Solve the LP relaxation of the model and // print out ofv for sake of comparisn siP->initialSolve(); double lpRelaxBefore=siP->getObjValue(); assert( eq(lpRelaxBefore, 6875.) ); double mycs[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; siP->setColSolution(mycs); #ifdef CGL_DEBUG printf("\n\nOrig LP min=%f\n",lpRelaxBefore); #endif OsiCuts cuts; // Test generateCuts method kccg.generateCuts(*siP,cuts); OsiSolverInterface::ApplyCutsReturnCode rc = siP->applyCuts(cuts); siP->resolve(); double lpRelaxAfter=siP->getObjValue(); assert( eq(lpRelaxAfter, 7125) ); #ifdef CGL_DEBUG printf("\n\nOrig LP min=%f\n",lpRelaxBefore); printf("\n\nFinal LP min=%f\n",lpRelaxAfter); #endif assert( lpRelaxBefore < lpRelaxAfter ); // Optimal IP solution to p0201 int objIndices[22] = { 8, 10, 21, 38, 39, 56, 60, 74, 79, 92, 94, 110, 111, 128, 132, 146, 151,164, 166, 182,183, 200 }; CoinPackedVector p0201(22,objIndices,1.0); // Sanity check const double * objective=siP->getObjCoefficients(); double ofv =0 ; int r; for (r=0; r<nCols; r++){ ofv=ofv + p0201[r]*objective[r]; } CoinRelFltEq eq; assert( eq(ofv,7615.0) ); //printf("p0201 optimal ofv = %g\n",ofv); int nRowCuts = cuts.sizeRowCuts(); OsiRowCut rcut; CoinPackedVector rpv; for (i=0; i<nRowCuts; i++){ rcut = cuts.rowCut(i); rpv = rcut.row(); double p0201Sum = (rpv*p0201).sum(); assert (p0201Sum <= rcut.ub() ); } delete siP; } // see if I get the same covers that N&W get { OsiSolverInterface * siP=baseSiP->clone(); std::string fn(mpsDir+"nw460"); siP->readMps(fn.c_str(),"mps"); // All integer variables should be binary. // Assert that this is true. for ( i = 0; i < siP->getNumCols(); i++ ) if ( siP->isInteger(i) ) assert(siP->getColUpper()[i]==1.0 && siP->isBinary(i)); CglKnapsackCover kccg; // Solve the LP relaxation of the model and // print out ofv for sake of comparison siP->initialSolve(); double lpRelaxBefore=siP->getObjValue(); assert( eq(lpRelaxBefore, -225.68951787852194) ); double mycs[] = {0.7099213482046447, 0, 0.34185802225477174, 1, 1, 0, 1, 1, 0}; siP->setColSolution(mycs); OsiCuts cuts; // Test generateCuts method kccg.generateCuts(*siP,cuts); OsiSolverInterface::ApplyCutsReturnCode rc = siP->applyCuts(cuts); siP->resolve(); double lpRelaxAfter=siP->getObjValue(); assert( eq(lpRelaxAfter, -176) ); #ifdef CGL_DEBUG printf("\n\nOrig LP min=%f\n",lpRelaxBefore); printf("\n\nFinal LP min=%f\n",lpRelaxAfter); #endif #ifdef MJS assert( lpRelaxBefore < lpRelaxAfter ); #endif int nRowCuts = cuts.sizeRowCuts(); OsiRowCut rcut; CoinPackedVector rpv; for (i=0; i<nRowCuts; i++){ rcut = cuts.rowCut(i); rpv = rcut.row(); int j; printf("Row cut number %i has rhs = %g\n",i,rcut.ub()); for (j=0; j<rpv.getNumElements(); j++){ printf("index %i, element %g\n", rpv.getIndices()[j], rpv.getElements()[j]); } printf("\n"); } delete siP; } // Debugging: try "exmip1.mps" { // Setup OsiSolverInterface * siP = baseSiP->clone(); std::string fn(mpsDir+"exmip1"); siP->readMps(fn.c_str(),"mps"); // All integer variables should be binary. // Assert that this is true. for ( i = 0; i < siP->getNumCols(); i++ ) if ( siP->isInteger(i) ) assert(siP->getColUpper()[i]==1.0 && siP->isBinary(i)); CglKnapsackCover kccg; // Solve the LP relaxation of the model and // print out ofv for sake of comparison siP->initialSolve(); double lpRelaxBefore=siP->getObjValue(); assert( eq(lpRelaxBefore, 3.2368421052631575) ); double mycs[] = {2.5, 0, 0, 0.6428571428571429, 0.5, 4, 0, 0.26315789473684253}; siP->setColSolution(mycs); // Test generateCuts method OsiCuts cuts; kccg.generateCuts(*siP,cuts); OsiSolverInterface::ApplyCutsReturnCode rc = siP->applyCuts(cuts); siP->resolve(); double lpRelaxAfter=siP->getObjValue(); assert( eq(lpRelaxAfter, 3.2368421052631575) ); #ifdef CGL_DEBUG printf("\n\nOrig LP min=%f\n",lpRelaxBefore); printf("\n\nFinal LP min=%f\n",lpRelaxAfter); #endif assert( lpRelaxBefore <= lpRelaxAfter ); delete siP; } #ifdef CGL_DEBUG // See what findLPMostViolatedMinCover for knapsack with 2 elements does { int nCols = 2; int row = 1; CoinPackedVector krow; double e[2] = {5,10}; int ii[2] = {0,1}; krow.setVector(nCols,ii,e); double b=11; double xstar[2] = {.2,.9}; CoinPackedVector cover; CoinPackedVector remainder; CglKnapsackCover kccg; kccg.findLPMostViolatedMinCover(nCols, row, krow, b, xstar, cover, remainder); printf("num in cover = %i\n",cover.getNumElements()); int j; for (j=0; j<cover.getNumElements(); j++){ printf(" index %i element % g\n", cover.getIndices()[j], cover.getElements()[j]); } } #endif #ifdef CGL_DEBUG // see what findLPMostViolatedMinCover does { int nCols = 5; int row = 1; CoinPackedVector krow; double e[5] = {1,1,1,1,10}; int ii[5] = {0,1,2,3,4}; krow.setVector(nCols,ii,e); double b=11; double xstar[5] = {.9,.9,1,1,.1}; CoinPackedVector cover; CoinPackedVector remainder; CglKnapsackCover kccg; kccg.findLPMostViolatedMinCover(nCols, row, krow, b, xstar, cover, remainder); printf("num in cover = %i\n",cover.getNumElements()); int j; for (j=0; j<cover.getNumElements(); j++){ printf(" index %i element % g\n", cover.getIndices()[j], cover.getElements()[j]); } } #endif }