Skip to content

Commit

Permalink
colcuts in gomory, modify probing etc
Browse files Browse the repository at this point in the history
  • Loading branch information
jjhforrest committed Dec 3, 2023
1 parent 3110a8d commit 745abaa
Show file tree
Hide file tree
Showing 13 changed files with 2,504 additions and 292 deletions.
3 changes: 3 additions & 0 deletions src/CglCommon/CglTreeInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class CGLLIB_EXPORT CglTreeInfo {
1024 - in must call again mode or after everything mode
2048 - playing around in probing
4096 - save number affected by probing
8192 - problem found to be infeasible
16384 - just going for column cuts
32768 - do all integer columns
*/
int options;
/// Set true if in tree (to avoid ambiguity at first branch)
Expand Down
14 changes: 5 additions & 9 deletions src/CglFlowCover/CglFlowCover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,9 @@ void CglFlowCover::generateCuts(const OsiSolverInterface & si, OsiCuts & cs,
const int* colInd = matrixByRow.getIndices();
const CoinBigIndex* rowStart = matrixByRow.getVectorStarts();
const int* rowLength = matrixByRow.getVectorLengths();
int* ind = 0;
double* coef = 0;
int numberColumns = si.getNumCols();
int* ind = new int [numberColumns];
double* coef = new double [numberColumns];
int iRow;
CoinBigIndex iCol;

Expand All @@ -278,10 +278,6 @@ void CglFlowCover::generateCuts(const OsiSolverInterface & si, OsiCuts & cs,
const CoinBigIndex sta = rowStart[iRow]; // Start position of iRow
int rowLen = rowLength[iRow]; // iRow length / non-zero elements

if (ind != 0) { delete [] ind; ind = 0; }
ind = new int [rowLen];
if (coef != 0) { delete [] coef; coef = 0; }
coef = new double [rowLen];

CoinBigIndex lastPos = sta + rowLen;
double thisRhs = rhs[iRow];
Expand Down Expand Up @@ -344,8 +340,8 @@ void CglFlowCover::generateCuts(const OsiSolverInterface & si, OsiCuts & cs,
cs.rowCutPtr(i)->setGloballyValid();
}

if (ind != 0) { delete [] ind; ind = 0; }
if (coef != 0) { delete [] coef; coef = 0; }
delete [] ind;
delete [] coef;
}

//-------------------------------------------------------------------
Expand Down
76 changes: 70 additions & 6 deletions src/CglGomory/CglGomory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1686,17 +1686,81 @@ CglGomory::generateCuts(
abort();
}
#endif
if (number>1) {
#if MORE_GOMORY_CUTS<2
nTotalEls -= number;
cs.insertIfNotDuplicate(rc);
#else
if(number<saveLimit) {
nTotalEls -= number;
cs.insertIfNotDuplicate(rc);
#else
if(number<saveLimit) {
nTotalEls -= number;
cs.insertIfNotDuplicate(rc);
} else {
longCuts.insertIfNotDuplicate(rc);
}
#endif
} else {
longCuts.insertIfNotDuplicate(rc);
// singleton row cut!
double lb = bounds[0];
double ub = bounds[1];
double value = packed[0];
int iColumn = cutIndex[0];
double lbCol = colLower[iColumn];
double ubCol = colUpper[iColumn];
// turn lb,ub into new bounds on column
if (lb==-COIN_DBL_MAX) {
if (value<0) {
lb = ub/value;
if (intVar[iColumn])
lb = ceil(lb-1.0e-4);
ub = ubCol;
} else {
ub = ub/value;
if (intVar[iColumn])
ub = floor(ub+1.0e-4);
lb = lbCol;
}
} else if (ub==COIN_DBL_MAX) {
if (value>0) {
lb = lb/value;
if (intVar[iColumn])
lb = ceil(lb-1.0e-4);
ub = ubCol;
} else {
ub = lb/value;
if (intVar[iColumn])
ub = floor(ub+1.0e-4);
lb = lbCol;
}
} else {
abort();
}
if (lb>ub+1.0e-4) {
// infeasible
//printf("CUTinf\n");
OsiRowCut rc;
rc.setRow(0,cutIndex,packed,false);
rc.setLb(1.0);
rc.setUb(0.0);
cs.insertIfNotDuplicate(rc);
} else if (lb>lbCol || ub<ubCol) {
if (!intVar[iColumn]) {
// think
//printf("CUTnotint\n");
} else {
OsiColCut cc;
if (lb>lbCol)
cc.setLbs(1,&iColumn,&lb);
if (ub<ubCol)
cc.setUbs(1,&iColumn,&ub);
cs.insert(cc);
//printf("CUT %g<=%g -> %g<= %g\n",
// colLower[iColumn],colUpper[iColumn],
// lb,ub);
}
} else {
//printf("CUT whynone\n");
}
}
#endif
//printf("nTot %d kCol %d iCol %d ibasic %d\n",
// nTotalEls,kColumn,iColumn,iBasic);
numberAdded++;
Expand Down
50 changes: 49 additions & 1 deletion src/CglGomory/CglGomoryTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,50 @@
#include "CoinWarmStartBasis.hpp"
#include "CglGomory.hpp"


void convertColumnCuts(OsiCuts & osicuts)
{
int nColCuts = osicuts.sizeColCuts();
if (nColCuts) {
std::cout<<"There are "<<nColCuts<<" gomory column cuts! - converting"
<<std::endl;
// convert to row cut
for (int i=0;i<nColCuts;i++) {
const OsiColCut * cut = osicuts.colCutPtr(i);
const CoinPackedVector lbs = cut->lbs();
const CoinPackedVector ubs = cut->ubs();
int ncols;
const int * cols;
const double * values;
double one = -1.0;
ncols = lbs.getNumElements();
cols = lbs.getIndices();
values = lbs.getElements();
for (int j=0;j<ncols;j++) {
int jColumn = cols[j];
double value = values[j];
// convert to <=
OsiRowCut rc;
rc.setRow(1,&jColumn,&one,false);
rc.setLb(-COIN_DBL_MAX);
rc.setUb(-value);
osicuts.insertIfNotDuplicate(rc);
}
one = 1.0;
ncols = ubs.getNumElements();
cols = ubs.getIndices();
values = ubs.getElements();
for (int j=0;j<ncols;j++) {
int jColumn = cols[j];
double value = values[j];
OsiRowCut rc;
rc.setRow(1,&jColumn,&one,false);
rc.setLb(-COIN_DBL_MAX);
rc.setUb(value);
osicuts.insertIfNotDuplicate(rc);
}
}
}
}
//--------------------------------------------------------------------------
// ** At present this does not use any solver
void
Expand Down Expand Up @@ -531,6 +574,8 @@ CglGomoryUnitTest(
/* objective,*/ colsol1,
colLower, colUpper,
rowLower, rowUpper, intVar, &warm);
// new version may create a column cut if just one element
convertColumnCuts(osicuts);
nRowCuts = osicuts.sizeRowCuts();
std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
assert (nRowCuts==1);
Expand Down Expand Up @@ -742,6 +787,7 @@ CglGomoryUnitTest(
/*objective,*/ colsol1,
colLower, colUpper,
rowLower, rowUpper, intVar, &warm);
convertColumnCuts(osicuts);
nRowCuts = osicuts.sizeRowCuts();
std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
assert (nRowCuts==1);
Expand Down Expand Up @@ -1234,6 +1280,7 @@ CglGomoryUnitTest(
/*objective,*/ colsol1,
colLower, colUpper,
rowLower, rowUpper, intVar, &warm);
convertColumnCuts(osicuts);
nRowCuts = osicuts.sizeRowCuts();
std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
assert (nRowCuts==1);
Expand Down Expand Up @@ -1367,6 +1414,7 @@ CglGomoryUnitTest(
/*objective,*/ colsol1,
colLower, colUpper,
rowLower, rowUpper, intVar, &warm);
convertColumnCuts(osicuts);
nRowCuts = osicuts.sizeRowCuts();
std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
assert (nRowCuts==1);
Expand Down
5 changes: 2 additions & 3 deletions src/CglKnapsackCover/CglKnapsackCover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "CoinSort.hpp"
#include "CoinPackedMatrix.hpp"
#include "OsiRowCutDebugger.hpp"
#define GUBCOVER 1
//#define GUBCOVER 1
//#define PRINT_DEBUG
//#define CGL_DEBUG 1
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -70,7 +70,6 @@ void CglKnapsackCover::generateCuts(const OsiSolverInterface& si, OsiCuts& cs,
// For each row point to vub variable
// -1 if no vub
// -2 if can skip row for knapsacks

int * vub = new int [nRows];

// Now vubValue are for positive coefficients and vlbValue for negative
Expand Down Expand Up @@ -3905,7 +3904,7 @@ CglKnapsackCover::createCliques( OsiSolverInterface & si,
}
}
int iUpper = upperValue > INT_MAX ? INT_MAX : static_cast<int> (floor(upperValue+1.0e-5));
int iLower = lowerValue < INT_MIN ? INT_MIN : static_cast<int> (ceil(lowerValue-1.0e-5));
int iLower = lowerValue < -INT_MIN ? -INT_MIN : static_cast<int> (ceil(lowerValue-1.0e-5));
int state=0;
if (upperValue<1.0e6) {
if (iUpper==1-numberM1)
Expand Down
4 changes: 4 additions & 0 deletions src/CglPreProcess/CglPreProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7098,6 +7098,10 @@ CglPreProcess::modified(OsiSolverInterface *model,
probingCut->setMaxProbeRoot(CoinMax(saveMaxProbe, 1000));
probingCut->setMaxElementsRoot(CoinMax(saveMaxElements, 2000));
int maxLook = CoinMin(numberColumns, numberRows)/2;
if ((options_&16)!=0) {
maxLook = numberColumns;
info.options |= 32768;
}
maxLook = CoinMin(maxLook,2000);
probingCut->setMaxLookRoot(CoinMax(saveMaxLook, maxLook));
options_ &= ~16;
Expand Down
Loading

0 comments on commit 745abaa

Please sign in to comment.