CoinWarmStartBasis *CoinPrePostsolveMatrix::getStatus () { int n = ncols_ ; int m = nrows_ ; CoinWarmStartBasis *wsb = new CoinWarmStartBasis() ; wsb->setSize(n,m) ; for (int j = 0 ; j < n ; j++) { CoinWarmStartBasis::Status statj = CoinWarmStartBasis::Status(getColumnStatus(j)) ; wsb->setStructStatus(j,statj) ; } for (int i = 0 ; i < m ; i++) { CoinWarmStartBasis::Status stati = CoinWarmStartBasis::Status(getRowStatus(i)) ; wsb->setArtifStatus(i,stati) ; } return (wsb) ; }
//-------------------------------------------------------------------------- // ** At present this does not use any solver void CglGomoryUnitTest( const OsiSolverInterface * baseSiP, const std::string mpsDir ) { CoinRelFltEq eq(0.000001); // Test default constructor { CglGomory aGenerator; assert (aGenerator.getLimit()==50); assert (aGenerator.getAway()==0.05); } // Test copy & assignment etc { CglGomory rhs; { CglGomory bGenerator; bGenerator.setLimit(99); bGenerator.setAway(0.2); CglGomory cGenerator(bGenerator); rhs=bGenerator; assert (rhs.getLimit()==99); assert (rhs.getAway()==0.2); } } // Test explicit form - all integer (pg 125 Wolsey) if (1) { OsiCuts osicuts; CglGomory test1; int i; int nOldCuts=0,nRowCuts; // matrix data //deliberate hiccup of 2 between 0 and 1 CoinBigIndex start[5]={0,4,7,8,9}; int length[5]={2,3,1,1,1}; int rows[11]={0,2,-1,-1,0,1,2,0,1,2}; double elements[11]={7.0,2.0,1.0e10,1.0e10,-2.0,1.0,-2.0,1,1,1}; CoinPackedMatrix matrix(true,3,5,8,elements,rows,start,length); // rim data (objective not used just yet) double rowLower[5]={14.0,3.0,3.0,1.0e10,1.0e10}; double rowUpper[5]={14.0,3.0,3.0,-1.0e10,-1.0e10}; double colLower[7]={0.0,0.0,0.0,0.0,0.0,0.0,0.0}; double colUpper[7]={100.0,100.0,100.0,100.0,100.0,100.0,100.0}; // integer char intVar[7]={2,2,2,2,2,2,2}; // basis 1 int rowBasis1[3]={-1,-1,-1}; int colBasis1[5]={1,1,-1,-1,1}; CoinWarmStartBasis warm; warm.setSize(5,3); for (i=0;i<3;i++) { if (rowBasis1[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<5;i++) { if (colBasis1[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 1 double colsol1[5]={20.0/7.0,3.0,0.0,0.0,23.0/7.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol1, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==2); // cuts always <= int testCut=0; // test first cut as stronger double rhs=-6.0; double testCut1[5]={0.0,0.0,-1.0,-2.0,0.0}; double * cut = testCut1; double * colsol = colsol1; for (i=nOldCuts; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; 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; for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } double ub=rcut.ub(); #ifdef CGL_DEBUG double lb=rcut.lb(); 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 (i-nOldCuts==testCut) { assert( eq(rhs,ub)); assert(n==2); for (k=0; k<n; k++){ int column=indices[k]; assert (eq(cut[column],elements[k])); } // add cut // explicit slack matrix.setDimensions(-1,6); rpv.insert(5,1.0*7.0); // to get cut in book rowLower[3]=ub; rowUpper[3]=ub; matrix.appendRow(rpv); } } nOldCuts=nRowCuts; // basis 2 int rowBasis2[4]={-1,-1,-1,-1}; int colBasis2[6]={1,1,1,1,-1,-1}; warm.setSize(6,4); for (i=0;i<4;i++) { if (rowBasis2[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<6;i++) { if (colBasis2[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 2 double colsol2[6]={2.0,0.5,1.0,2.5,0.0,0.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol2, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts-nOldCuts==2); // cuts always <= testCut=0; // test first cut as stronger rhs=-1.0; double testCut2[6]={0.0,0.0,0.0,0.0,-1.0,0.0}; cut = testCut2; colsol = colsol2; for (i=nOldCuts; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; 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; for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } double ub=rcut.ub(); #ifdef CGL_DEBUG double lb=rcut.lb(); 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 (i-nOldCuts==testCut) { assert( eq(rhs,ub)); assert(n==1); for (k=0; k<n; k++){ int column=indices[k]; assert (eq(cut[column],elements[k])); } // add cut // explicit slack matrix.setDimensions(-1,7); rpv.insert(6,1.0); rowLower[4]=ub; rowUpper[4]=ub; matrix.appendRow(rpv); } } nOldCuts=nRowCuts; // basis 3 int rowBasis3[5]={-1,-1,-1,-1,-1}; int colBasis3[7]={1,1,1,1,1,-1,-1}; warm.setSize(7,5); for (i=0;i<5;i++) { if (rowBasis3[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<7;i++) { if (colBasis3[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 3 double colsol3[7]={2.0,1.0,2.0,2.0,1.0,0.0,0.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol3, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==nOldCuts); } // Test explicit form - this time with x4 flipped if (1) { OsiCuts osicuts; CglGomory test1; int i; int nOldCuts=0,nRowCuts; // matrix data //deliberate hiccup of 2 between 0 and 1 CoinBigIndex start[5]={0,4,7,8,9}; int length[5]={2,3,1,1,1}; int rows[11]={0,2,-1,-1,0,1,2,0,1,2}; double elements[11]={7.0,2.0,1.0e10,1.0e10,-2.0,1.0,-2.0,1,-1,1}; CoinPackedMatrix matrix(true,3,5,8,elements,rows,start,length); // rim data (objective not used just yet) double rowLower[5]={14.0,-5.0,3.0,1.0e10,1.0e10}; double rowUpper[5]={14.0,-5.0,3.0,-1.0e10,-1.0e10}; double colLower[7]={0.0,0.0,0.0,0.0,0.0,0.0,0.0}; double colUpper[7]={100.0,100.0,100.0,8.0,100.0,100.0,100.0}; // integer char intVar[7]={2,2,2,2,2,2,2}; // basis 1 int rowBasis1[3]={-1,-1,-1}; int colBasis1[5]={1,1,-1,-1,1}; CoinWarmStartBasis warm; warm.setSize(5,3); for (i=0;i<3;i++) { if (rowBasis1[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<5;i++) { if (colBasis1[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 1 double colsol1[5]={20.0/7.0,3.0,0.0,8.0,23.0/7.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol1, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==2); // cuts always <= int testCut=0; // test first cut as stronger double rhs=10.0; double testCut1[5]={0.0,0.0,-1.0,2.0,0.0}; double * cut = testCut1; double * colsol = colsol1; for (i=nOldCuts; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; 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; for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } double ub=rcut.ub(); #ifdef CGL_DEBUG double lb=rcut.lb(); 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 (i-nOldCuts==testCut) { assert( eq(rhs,ub)); assert(n==2); for (k=0; k<n; k++){ int column=indices[k]; assert (eq(cut[column],elements[k])); } // add cut // explicit slack matrix.setDimensions(-1,6); rpv.insert(5,1.0*7.0); // to get cut in book rowLower[3]=ub; rowUpper[3]=ub; matrix.appendRow(rpv); } } nOldCuts=nRowCuts; // basis 2 int rowBasis2[4]={-1,-1,-1,-1}; int colBasis2[6]={1,1,1,1,-1,-1}; warm.setSize(6,4); for (i=0;i<4;i++) { if (rowBasis2[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<6;i++) { if (colBasis2[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 2 double colsol2[6]={2.0,0.5,1.0,5.5,0.0,0.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol2, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts-nOldCuts==2); // cuts always <= testCut=0; // test first cut as stronger rhs=-1.0; double testCut2[6]={0.0,0.0,0.0,0.0,-1.0,0.0}; cut = testCut2; colsol = colsol2; for (i=nOldCuts; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; 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; for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } double ub=rcut.ub(); #ifdef CGL_DEBUG double lb=rcut.lb(); 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 (i-nOldCuts==testCut) { assert( eq(rhs,ub)); assert(n==1); for (k=0; k<n; k++){ int column=indices[k]; assert (eq(cut[column],elements[k])); } // add cut // explicit slack matrix.setDimensions(-1,7); rpv.insert(6,1.0); rowLower[4]=ub; rowUpper[4]=ub; matrix.appendRow(rpv); } } nOldCuts=nRowCuts; // basis 3 int rowBasis3[5]={-1,-1,-1,-1,-1}; int colBasis3[7]={1,1,1,1,1,-1,-1}; warm.setSize(7,5); for (i=0;i<5;i++) { if (rowBasis3[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<7;i++) { if (colBasis3[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 3 double colsol3[7]={2.0,1.0,2.0,6.0,1.0,0.0,0.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol3, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==nOldCuts); } // Test with slacks if (1) { OsiCuts osicuts; CglGomory test1; int i; int nOldCuts=0,nRowCuts; // matrix data //deliberate hiccup of 2 between 0 and 1 CoinBigIndex start[5]={0,4}; int length[5]={2,3}; int rows[11]={0,2,-1,-1,0,1,2}; double elements[11]={7.0,2.0,1.0e10,1.0e10,-2.0,1.0,-2.0}; CoinPackedMatrix matrix(true,3,2,5,elements,rows,start,length); // rim data (objective not used just yet) double rowLower[5]={-1.0e10,-1.0e10,-1.0e10,1.0e10,1.0e10}; double rowUpper[5]={14.0,3.0,3.0,-1.0e10,-1.0e10}; double colLower[2]={0.0,0.0}; double colUpper[2]={100.0,100.0}; // integer char intVar[2]={2,2}; // basis 1 int rowBasis1[3]={-1,-1,1}; int colBasis1[2]={1,1}; CoinWarmStartBasis warm; warm.setSize(2,3); for (i=0;i<3;i++) { if (rowBasis1[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<2;i++) { if (colBasis1[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 1 double colsol1[2]={20.0/7.0,3.0}; test1.generateCuts(NULL, osicuts, matrix, /* objective,*/ colsol1, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==1); // cuts always <= int testCut=0; // test first cut as stronger double rhs=2.0; double testCut1[2]={1.0,0.0}; double * cut = testCut1; double * colsol = colsol1; for (i=nOldCuts; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; 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; for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } double ub=rcut.ub(); #ifdef CGL_DEBUG double lb=rcut.lb(); 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 (i-nOldCuts==testCut) { assert( eq(rhs,ub)); assert(n==1); for (k=0; k<n; k++){ int column=indices[k]; assert (eq(cut[column],elements[k])); } // add cut rowLower[3]=-1.0e100; rowUpper[3]=ub; matrix.appendRow(rpv); } } nOldCuts=nRowCuts; // basis 2 int rowBasis2[4]={1,1,-1,-1}; int colBasis2[2]={1,1}; warm.setSize(2,4); for (i=0;i<4;i++) { if (rowBasis2[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<2;i++) { if (colBasis2[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 2 double colsol2[2]={2.0,0.5}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol2, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts-nOldCuts==1); // cuts always <= testCut=0; // test first cut as stronger rhs=1.0; double testCut2[2]={1.0,-1.0}; cut = testCut2; colsol = colsol2; for (i=nOldCuts; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; 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; for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } double ub=rcut.ub(); #ifdef CGL_DEBUG double lb=rcut.lb(); 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 (i-nOldCuts==testCut) { assert( eq(rhs,ub)); assert(n==2); for (k=0; k<n; k++){ int column=indices[k]; assert (eq(cut[column],elements[k])); } // add cut rowLower[4]=-1.0e100; rowUpper[4]=ub; matrix.appendRow(rpv); } } nOldCuts=nRowCuts; // basis 3 int rowBasis3[5]={1,1,1,-1,-1}; int colBasis3[2]={1,1}; warm.setSize(2,5); for (i=0;i<5;i++) { if (rowBasis3[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<2;i++) { if (colBasis3[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 3 double colsol3[2]={2.0,1.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol3, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==nOldCuts); } // swap some rows to G if (1) { OsiCuts osicuts; CglGomory test1; int i; int nOldCuts=0,nRowCuts; // matrix data //deliberate hiccup of 2 between 0 and 1 CoinBigIndex start[5]={0,4}; int length[5]={2,3}; int rows[11]={0,2,-1,-1,0,1,2}; double elements[11]={-7.0,-2.0,1.0e10,1.0e10,+2.0,1.0,+2.0}; CoinPackedMatrix matrix(true,3,2,5,elements,rows,start,length); // rim data (objective not used just yet) double rowUpper[5]={1.0e10,3.0,1.0e10,-1.0e10,-1.0e10}; double rowLower[5]={-14.0,-1.0e10,-3.0,1.0e10,1.0e10}; double colLower[2]={0.0,0.0}; double colUpper[2]={100.0,100.0}; // integer char intVar[2]={2,2}; // basis 1 int rowBasis1[3]={-1,-1,1}; int colBasis1[2]={1,1}; CoinWarmStartBasis warm; warm.setSize(2,3); for (i=0;i<3;i++) { if (rowBasis1[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<2;i++) { if (colBasis1[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 1 double colsol1[2]={20.0/7.0,3.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol1, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==1); // cuts always <= int testCut=0; // test first cut as stronger double rhs=2.0; double testCut1[2]={1.0,0.0}; double * cut = testCut1; double * colsol = colsol1; for (i=nOldCuts; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; 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; for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } double ub=rcut.ub(); #ifdef CGL_DEBUG double lb=rcut.lb(); 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 (i-nOldCuts==testCut) { assert( eq(rhs,ub)); assert(n==1); for (k=0; k<n; k++){ int column=indices[k]; assert (eq(cut[column],elements[k])); } // add cut rowLower[3]=-1.0e100; rowUpper[3]=ub; matrix.appendRow(rpv); } } nOldCuts=nRowCuts; // basis 2 int rowBasis2[4]={1,1,-1,-1}; int colBasis2[2]={1,1}; warm.setSize(2,4); for (i=0;i<4;i++) { if (rowBasis2[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<2;i++) { if (colBasis2[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 2 double colsol2[2]={2.0,0.5}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol2, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts-nOldCuts==1); // cuts always <= testCut=0; // test first cut as stronger rhs=1.0; double testCut2[2]={1.0,-1.0}; cut = testCut2; colsol = colsol2; for (i=nOldCuts; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; 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; for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } double ub=rcut.ub(); #ifdef CGL_DEBUG double lb=rcut.lb(); 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 (i-nOldCuts==testCut) { assert( eq(rhs,ub)); assert(n==2); for (k=0; k<n; k++){ int column=indices[k]; assert (eq(cut[column],elements[k])); } // add cut rowLower[4]=-1.0e100; rowUpper[4]=ub; matrix.appendRow(rpv); } } nOldCuts=nRowCuts; // basis 3 int rowBasis3[5]={1,1,1,-1,-1}; int colBasis3[2]={1,1}; warm.setSize(2,5); for (i=0;i<5;i++) { if (rowBasis3[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<2;i++) { if (colBasis3[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 3 double colsol3[2]={2.0,1.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol3, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==nOldCuts); } // NOW mixed integer gomory cuts // Test explicit form - (pg 130 Wolsey) // Some arrays left same size as previously although not used in full if (1) { OsiCuts osicuts; CglGomory test1; int i; int nOldCuts=0,nRowCuts; // matrix data //deliberate hiccup of 2 between 0 and 1 CoinBigIndex start[5]={0,4,7,8,9}; int length[5]={2,3,1,1,1}; int rows[11]={0,2,-1,-1,0,1,2,0,1,2}; double elements[11]={7.0,2.0,1.0e10,1.0e10,-2.0,1.0,-2.0,1,1,1}; CoinPackedMatrix matrix(true,3,5,8,elements,rows,start,length); // rim data (objective not used just yet) double rowLower[5]={14.0,3.0,3.0,1.0e10,1.0e10}; double rowUpper[5]={14.0,3.0,3.0,-1.0e10,-1.0e10}; double colLower[7]={0.0,0.0,0.0,0.0,0.0,0.0,0.0}; double colUpper[7]={100.0,100.0,100.0,100.0,100.0,100.0,100.0}; // integer char intVar[7]={2,0,0,0,0,0,0}; // basis 1 int rowBasis1[3]={-1,-1,-1}; int colBasis1[5]={1,1,-1,-1,1}; CoinWarmStartBasis warm; warm.setSize(5,3); for (i=0;i<3;i++) { if (rowBasis1[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<5;i++) { if (colBasis1[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 1 double colsol1[5]={20.0/7.0,3.0,0.0,0.0,23.0/7.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol1, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==1); // cuts always <= int testCut=0; // test first cut as stronger double rhs=-6.0/7.0; double testCut1[5]={0.0,0.0,-1.0/7.0,-2.0/7.0,0.0}; double * cut = testCut1; double * colsol = colsol1; for (i=nOldCuts; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; 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; for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } double ub=rcut.ub(); #ifdef CGL_DEBUG double lb=rcut.lb(); 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 (i-nOldCuts==testCut) { assert( eq(rhs,ub)); assert(n==2); for (k=0; k<n; k++){ int column=indices[k]; assert (eq(cut[column],elements[k])); } // add cut // explicit slack matrix.setDimensions(-1,6); rpv.insert(5,1.0); // to get cut in book rowLower[3]=ub; rowUpper[3]=ub; matrix.appendRow(rpv); } } nOldCuts=nRowCuts; // basis 2 int rowBasis2[4]={-1,-1,-1,-1}; int colBasis2[6]={1,1,1,1,-1,-1}; warm.setSize(6,4); for (i=0;i<4;i++) { if (rowBasis2[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<6;i++) { if (colBasis2[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 2 double colsol2[6]={2.0,0.5,1.0,2.5,0.0,0.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol2, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==nOldCuts); } // Test explicit form - this time with x4 flipped if (1) { OsiCuts osicuts; CglGomory test1; int i; int nOldCuts=0,nRowCuts; // matrix data //deliberate hiccup of 2 between 0 and 1 CoinBigIndex start[5]={0,4,7,8,9}; int length[5]={2,3,1,1,1}; int rows[11]={0,2,-1,-1,0,1,2,0,1,2}; double elements[11]={7.0,2.0,1.0e10,1.0e10,-2.0,1.0,-2.0,1,-1,1}; CoinPackedMatrix matrix(true,3,5,8,elements,rows,start,length); // rim data (objective not used just yet) double rowLower[5]={14.0,-5.0,3.0,1.0e10,1.0e10}; double rowUpper[5]={14.0,-5.0,3.0,-1.0e10,-1.0e10}; double colLower[7]={0.0,0.0,0.0,0.0,0.0,0.0,0.0}; double colUpper[7]={100.0,100.0,100.0,8.0,100.0,100.0,100.0}; // integer char intVar[7]={2,0,0,0,0,0,0}; // basis 1 int rowBasis1[3]={-1,-1,-1}; int colBasis1[5]={1,1,-1,-1,1}; CoinWarmStartBasis warm; warm.setSize(5,3); for (i=0;i<3;i++) { if (rowBasis1[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<5;i++) { if (colBasis1[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 1 double colsol1[5]={20.0/7.0,3.0,0.0,8.0,23.0/7.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol1, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==1); // cuts always <= int testCut=0; double rhs=10.0/7.0; double testCut1[5]={0.0,0.0,-1.0/7.0,2.0/7.0,0.0}; double * cut = testCut1; double * colsol = colsol1; for (i=nOldCuts; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; 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; for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } double ub=rcut.ub(); #ifdef CGL_DEBUG double lb=rcut.lb(); 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 (i-nOldCuts==testCut) { assert( eq(rhs,ub)); assert(n==2); for (k=0; k<n; k++){ int column=indices[k]; assert (eq(cut[column],elements[k])); } // add cut // explicit slack matrix.setDimensions(-1,6); rpv.insert(5,1.0); // to get cut in book rowLower[3]=ub; rowUpper[3]=ub; matrix.appendRow(rpv); } } nOldCuts=nRowCuts; // basis 2 int rowBasis2[4]={-1,-1,-1,-1}; int colBasis2[6]={1,1,1,1,-1,-1}; warm.setSize(6,4); for (i=0;i<4;i++) { if (rowBasis2[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<6;i++) { if (colBasis2[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 2 double colsol2[6]={2.0,0.5,1.0,5.5,0.0,0.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol2, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==nOldCuts); } // Test with slacks if (1) { OsiCuts osicuts; CglGomory test1; int i; int nOldCuts=0,nRowCuts; // matrix data //deliberate hiccup of 2 between 0 and 1 CoinBigIndex start[5]={0,4}; int length[5]={2,3}; int rows[11]={0,2,-1,-1,0,1,2}; double elements[11]={7.0,2.0,1.0e10,1.0e10,-2.0,1.0,-2.0}; CoinPackedMatrix matrix(true,3,2,5,elements,rows,start,length); // rim data (objective not used just yet) double rowLower[5]={-1.0e10,-1.0e10,-1.0e10,1.0e10,1.0e10}; double rowUpper[5]={14.0,3.0,3.0,-1.0e10,-1.0e10}; double colLower[2]={0.0,0.0}; double colUpper[2]={100.0,100.0}; // integer char intVar[2]={2,0}; // basis 1 int rowBasis1[3]={-1,-1,1}; int colBasis1[2]={1,1}; CoinWarmStartBasis warm; warm.setSize(2,3); for (i=0;i<3;i++) { if (rowBasis1[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<2;i++) { if (colBasis1[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 1 double colsol1[2]={20.0/7.0,3.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol1, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==1); // cuts always <= int testCut=0; // test first cut as stronger double rhs=2.0; double testCut1[2]={1.0,0.0}; double * cut = testCut1; double * colsol = colsol1; for (i=nOldCuts; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; 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; for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } double ub=rcut.ub(); #ifdef CGL_DEBUG double lb=rcut.lb(); 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 (i-nOldCuts==testCut) { assert( eq(rhs,ub)); assert(n==1); for (k=0; k<n; k++){ int column=indices[k]; assert (eq(cut[column],elements[k])); } // add cut rowLower[3]=-1.0e100; rowUpper[3]=ub; matrix.appendRow(rpv); } } nOldCuts=nRowCuts; // basis 2 int rowBasis2[4]={1,1,-1,-1}; int colBasis2[2]={1,1}; warm.setSize(2,4); for (i=0;i<4;i++) { if (rowBasis2[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<2;i++) { if (colBasis2[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 2 double colsol2[2]={2.0,0.5}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol2, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==nOldCuts); } // swap some rows to G if (1) { OsiCuts osicuts; CglGomory test1; int i; int nOldCuts=0,nRowCuts; // matrix data //deliberate hiccup of 2 between 0 and 1 CoinBigIndex start[5]={0,4}; int length[5]={2,3}; int rows[11]={0,2,-1,-1,0,1,2}; double elements[11]={-7.0,-2.0,1.0e10,1.0e10,+2.0,1.0,+2.0}; CoinPackedMatrix matrix(true,3,2,5,elements,rows,start,length); // rim data (objective not used just yet) double rowUpper[5]={1.0e10,3.0,1.0e10,-1.0e10,-1.0e10}; double rowLower[5]={-14.0,-1.0e10,-3.0,1.0e10,1.0e10}; double colLower[2]={0.0,0.0}; double colUpper[2]={100.0,100.0}; // integer char intVar[2]={2,0}; // basis 1 int rowBasis1[3]={-1,-1,1}; int colBasis1[2]={1,1}; CoinWarmStartBasis warm; warm.setSize(2,3); for (i=0;i<3;i++) { if (rowBasis1[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<2;i++) { if (colBasis1[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 1 double colsol1[2]={20.0/7.0,3.0}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol1, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==1); // cuts always <= int testCut=0; // test first cut as stronger double rhs=2.0; double testCut1[2]={1.0,0.0}; double * cut = testCut1; double * colsol = colsol1; for (i=nOldCuts; i<nRowCuts; i++){ OsiRowCut rcut; CoinPackedVector rpv; 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; for (k=0; k<n; k++){ int column=indices[k]; sum2 += colsol[column]*elements[k]; } double ub=rcut.ub(); #ifdef CGL_DEBUG double lb=rcut.lb(); 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 (i-nOldCuts==testCut) { assert( eq(rhs,ub)); assert(n==1); for (k=0; k<n; k++){ int column=indices[k]; assert (eq(cut[column],elements[k])); } // add cut rowLower[3]=-1.0e100; rowUpper[3]=ub; matrix.appendRow(rpv); } } nOldCuts=nRowCuts; // basis 2 int rowBasis2[4]={1,1,-1,-1}; int colBasis2[2]={1,1}; warm.setSize(2,4); for (i=0;i<4;i++) { if (rowBasis2[i]<0) { warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setArtifStatus(i,CoinWarmStartBasis::basic); } } for (i=0;i<2;i++) { if (colBasis2[i]<0) { warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound); } else { warm.setStructStatus(i,CoinWarmStartBasis::basic); } } // solution 2 double colsol2[2]={2.0,0.5}; test1.generateCuts(NULL, osicuts, matrix, /*objective,*/ colsol2, colLower, colUpper, rowLower, rowUpper, intVar, &warm); nRowCuts = osicuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl; assert (nRowCuts==nOldCuts); } // Miplib3 problem p0033 if (1) { // Setup OsiSolverInterface * siP = baseSiP->clone(); std::string fn(mpsDir+"p0033"); siP->readMps(fn.c_str(),"mps"); siP->activateRowCutDebugger("p0033"); CglGomory test; // Solve the LP relaxation of the model and // print out ofv for sake of comparison siP->initialSolve(); double lpRelaxBefore=siP->getObjValue(); std::cout<<"Initial LP value: "<<lpRelaxBefore<<std::endl; assert( eq(lpRelaxBefore, 2520.5717391304347) ); // Fails with OsiCpx, OsiXpr: /********** 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); ****/ OsiCuts cuts; // Test generateCuts method test.generateCuts(*siP,cuts); int nRowCuts = cuts.sizeRowCuts(); std::cout<<"There are "<<nRowCuts<<" Gomory cuts"<<std::endl; assert(cuts.sizeRowCuts() > 0); OsiSolverInterface::ApplyCutsReturnCode rc = siP->applyCuts(cuts); siP->resolve(); double lpRelaxAfter=siP->getObjValue(); std::cout<<"LP value with cuts: "<<lpRelaxAfter<<std::endl; //assert( eq(lpRelaxAfter, 2592.1908295194507) ); assert( lpRelaxAfter> 2550.0 ); assert( lpRelaxBefore < lpRelaxAfter ); assert(lpRelaxAfter < 3089.1); delete siP; } }
void OsiPresolve::postsolve(bool updateStatus) { // Messages CoinMessages messages = CoinMessage(presolvedModel_->messages().language()); if (!presolvedModel_->isProvenOptimal()) { presolvedModel_->messageHandler()->message(COIN_PRESOLVE_NONOPTIMAL, messages) <<CoinMessageEol; } // this is the size of the original problem const int ncols0 = ncols_; const int nrows0 = nrows_; const CoinBigIndex nelems0 = nelems_; // reality check assert(ncols0==originalModel_->getNumCols()); assert(nrows0==originalModel_->getNumRows()); // this is the reduced problem int ncols = presolvedModel_->getNumCols(); int nrows = presolvedModel_->getNumRows(); double *acts = new double [nrows0]; double *sol = new double [ncols0]; CoinZeroN(acts,nrows0); CoinZeroN(sol,ncols0); unsigned char * rowstat=NULL; unsigned char * colstat = NULL; CoinWarmStartBasis * presolvedBasis = dynamic_cast<CoinWarmStartBasis*>(presolvedModel_->getWarmStart()); if (!presolvedBasis) updateStatus=false; if (updateStatus) { colstat = new unsigned char[ncols0+nrows0]; # ifdef ZEROFAULT memset(colstat,0,((ncols0+nrows0)*sizeof(char))) ; # endif rowstat = colstat + ncols0; int i; for (i=0;i<ncols;i++) { colstat[i] = presolvedBasis->getStructStatus(i); } for (i=0;i<nrows;i++) { rowstat[i] = presolvedBasis->getArtifStatus(i); } } delete presolvedBasis; # if PRESOLVE_CONSISTENCY > 0 if (updateStatus) { int basicCnt = 0 ; int i ; for (i = 0 ; i < ncols ; i++) { if (colstat[i] == CoinWarmStartBasis::basic) basicCnt++ ; } for (i = 0 ; i < nrows ; i++) { if (rowstat[i] == CoinWarmStartBasis::basic) basicCnt++ ; } assert (basicCnt == nrows) ; } # endif /* Postsolve back to the original problem. The CoinPostsolveMatrix object assumes ownership of sol, acts, colstat, and rowstat. */ CoinPostsolveMatrix prob(presolvedModel_, ncols0, nrows0, nelems0, presolvedModel_->getObjSense(), sol, acts, colstat, rowstat); postsolve(prob); # if PRESOLVE_CONSISTENCY > 0 if (updateStatus) { int basicCnt = 0 ; int i ; for (i = 0 ; i < ncols0 ; i++) { if (prob.getColumnStatus(i) == CoinWarmStartBasis::basic) basicCnt++ ; } for (i = 0 ; i < nrows0 ; i++) { if (prob.getRowStatus(i) == CoinWarmStartBasis::basic) basicCnt++ ; } assert (basicCnt == nrows0) ; } # endif originalModel_->setColSolution(sol); if (updateStatus) { CoinWarmStartBasis *basis = dynamic_cast<CoinWarmStartBasis *>(presolvedModel_->getEmptyWarmStart()); basis->setSize(ncols0,nrows0); int i; for (i=0;i<ncols0;i++) { CoinWarmStartBasis::Status status = static_cast<CoinWarmStartBasis::Status> (prob.getColumnStatus(i)); /* FIXME: these asserts seem correct, but seem to reveal some bugs in CoinPresolve */ // assert(status != CoinWarmStartBasis::atLowerBound || originalModel_->getColLower()[i] > -originalModel_->getInfinity()); // assert(status != CoinWarmStartBasis::atUpperBound || originalModel_->getColUpper()[i] < originalModel_->getInfinity()); basis->setStructStatus(i,status); } for (i=0;i<nrows0;i++) { CoinWarmStartBasis::Status status = static_cast<CoinWarmStartBasis::Status> (prob.getRowStatus(i)); /* FIXME: these asserts seem correct, but seem to reveal some bugs in CoinPresolve */ // assert(status != CoinWarmStartBasis::atUpperBound || originalModel_->getRowLower()[i] > -originalModel_->getInfinity()); // assert(status != CoinWarmStartBasis::atLowerBound || originalModel_->getRowUpper()[i] < originalModel_->getInfinity()); basis->setArtifStatus(i,status); } originalModel_->setWarmStart(basis); delete basis ; } }
void OsiIF::_loadBasis( Array<LPVARSTAT::STATUS> &lpVarStat, Array<SlackStat::STATUS> &slackStat) { int lps = lpVarStat.size(); int sls = slackStat.size(); CoinWarmStartBasis *ws = nullptr; ws = new CoinWarmStartBasis(); ws->setSize(numCols_, numRows_); if (osiLP_->getNumCols() > lps) { Logger::ifout() << "OsiIF::_loadBasis: mismatch in number of columns: OSI " << osiLP_->getNumCols() << ", Abacus: " << lps << "\n"; OGDF_THROW_PARAM(AlgorithmFailureException, ogdf::afcOsiIf); } for (int i = 0; i < numCols_; i++) ws->setStructStatus(i, lpVarStat2osi(lpVarStat[i])); if (osiLP_->getNumRows() > sls) { Logger::ifout() << "OsiIF::_loadBasis: mismatch in number of rows: OSI " << osiLP_->getNumCols() << ", Abacus: " << sls << "\n"; OGDF_THROW_PARAM(AlgorithmFailureException, ogdf::afcOsiIf); } for (int i = 0; i < numRows_; i++) ws->setArtifStatus(i, slackStat2osi(slackStat[i])); lpSolverTime_.start(); slackStatus_ = basisStatus_ = Missing; int status = 0; // FIXME loadBasis // better test whether the number of basic structurals is correct? if (ws->numberBasicStructurals() > 0) { status = osiLP_->setWarmStart(dynamic_cast<CoinWarmStart *> (ws)); if (ws_ != nullptr) delete ws_; ws_ = dynamic_cast<CoinWarmStartBasis*> (osiLP_->getWarmStart()); if (ws_ != nullptr) { delete[] cStat_; int nStructBytes = (int) ceil( ws_->getNumStructural() / 4.0); cStat_ = new char[nStructBytes]; for(int i = 0; i < nStructBytes; i++) { cStat_[i] = ws_->getStructuralStatus()[i]; } delete[] rStat_; int nArtBytes = (int) ceil( ws_->getNumArtificial() / 4.0 ); rStat_ = new char[nArtBytes]; for(int i = 0; i < nArtBytes; i++) { rStat_[i] = ws_->getArtificialStatus()[i]; } basisStatus_ = Available; } else basisStatus_ = Missing; } else status = 2; lpSolverTime_.stop(); delete ws; if (status == 0) { Logger::ifout() << "OsiIF::_loadBasis(): loading the new basis has failed. Status " << status << endl; // FIXME loadBasis return; } else return; }