Skip to content

Commit 745abaa

Browse files
committed
colcuts in gomory, modify probing etc
1 parent 3110a8d commit 745abaa

File tree

13 files changed

+2504
-292
lines changed

13 files changed

+2504
-292
lines changed

src/CglCommon/CglTreeInfo.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class CGLLIB_EXPORT CglTreeInfo {
3737
1024 - in must call again mode or after everything mode
3838
2048 - playing around in probing
3939
4096 - save number affected by probing
40+
8192 - problem found to be infeasible
41+
16384 - just going for column cuts
42+
32768 - do all integer columns
4043
*/
4144
int options;
4245
/// Set true if in tree (to avoid ambiguity at first branch)

src/CglFlowCover/CglFlowCover.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,9 @@ void CglFlowCover::generateCuts(const OsiSolverInterface & si, OsiCuts & cs,
257257
const int* colInd = matrixByRow.getIndices();
258258
const CoinBigIndex* rowStart = matrixByRow.getVectorStarts();
259259
const int* rowLength = matrixByRow.getVectorLengths();
260-
261-
int* ind = 0;
262-
double* coef = 0;
260+
int numberColumns = si.getNumCols();
261+
int* ind = new int [numberColumns];
262+
double* coef = new double [numberColumns];
263263
int iRow;
264264
CoinBigIndex iCol;
265265

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

281-
if (ind != 0) { delete [] ind; ind = 0; }
282-
ind = new int [rowLen];
283-
if (coef != 0) { delete [] coef; coef = 0; }
284-
coef = new double [rowLen];
285281

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

347-
if (ind != 0) { delete [] ind; ind = 0; }
348-
if (coef != 0) { delete [] coef; coef = 0; }
343+
delete [] ind;
344+
delete [] coef;
349345
}
350346

351347
//-------------------------------------------------------------------

src/CglGomory/CglGomory.cpp

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,17 +1686,81 @@ CglGomory::generateCuts(
16861686
abort();
16871687
}
16881688
#endif
1689+
if (number>1) {
16891690
#if MORE_GOMORY_CUTS<2
1690-
nTotalEls -= number;
1691-
cs.insertIfNotDuplicate(rc);
1692-
#else
1693-
if(number<saveLimit) {
16941691
nTotalEls -= number;
16951692
cs.insertIfNotDuplicate(rc);
1693+
#else
1694+
if(number<saveLimit) {
1695+
nTotalEls -= number;
1696+
cs.insertIfNotDuplicate(rc);
1697+
} else {
1698+
longCuts.insertIfNotDuplicate(rc);
1699+
}
1700+
#endif
16961701
} else {
1697-
longCuts.insertIfNotDuplicate(rc);
1702+
// singleton row cut!
1703+
double lb = bounds[0];
1704+
double ub = bounds[1];
1705+
double value = packed[0];
1706+
int iColumn = cutIndex[0];
1707+
double lbCol = colLower[iColumn];
1708+
double ubCol = colUpper[iColumn];
1709+
// turn lb,ub into new bounds on column
1710+
if (lb==-COIN_DBL_MAX) {
1711+
if (value<0) {
1712+
lb = ub/value;
1713+
if (intVar[iColumn])
1714+
lb = ceil(lb-1.0e-4);
1715+
ub = ubCol;
1716+
} else {
1717+
ub = ub/value;
1718+
if (intVar[iColumn])
1719+
ub = floor(ub+1.0e-4);
1720+
lb = lbCol;
1721+
}
1722+
} else if (ub==COIN_DBL_MAX) {
1723+
if (value>0) {
1724+
lb = lb/value;
1725+
if (intVar[iColumn])
1726+
lb = ceil(lb-1.0e-4);
1727+
ub = ubCol;
1728+
} else {
1729+
ub = lb/value;
1730+
if (intVar[iColumn])
1731+
ub = floor(ub+1.0e-4);
1732+
lb = lbCol;
1733+
}
1734+
} else {
1735+
abort();
1736+
}
1737+
if (lb>ub+1.0e-4) {
1738+
// infeasible
1739+
//printf("CUTinf\n");
1740+
OsiRowCut rc;
1741+
rc.setRow(0,cutIndex,packed,false);
1742+
rc.setLb(1.0);
1743+
rc.setUb(0.0);
1744+
cs.insertIfNotDuplicate(rc);
1745+
} else if (lb>lbCol || ub<ubCol) {
1746+
if (!intVar[iColumn]) {
1747+
// think
1748+
//printf("CUTnotint\n");
1749+
} else {
1750+
OsiColCut cc;
1751+
if (lb>lbCol)
1752+
cc.setLbs(1,&iColumn,&lb);
1753+
if (ub<ubCol)
1754+
cc.setUbs(1,&iColumn,&ub);
1755+
cs.insert(cc);
1756+
//printf("CUT %g<=%g -> %g<= %g\n",
1757+
// colLower[iColumn],colUpper[iColumn],
1758+
// lb,ub);
1759+
}
1760+
} else {
1761+
//printf("CUT whynone\n");
1762+
}
16981763
}
1699-
#endif
17001764
//printf("nTot %d kCol %d iCol %d ibasic %d\n",
17011765
// nTotalEls,kColumn,iColumn,iBasic);
17021766
numberAdded++;

src/CglGomory/CglGomoryTest.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,50 @@
1616
#include "CoinWarmStartBasis.hpp"
1717
#include "CglGomory.hpp"
1818

19-
19+
void convertColumnCuts(OsiCuts & osicuts)
20+
{
21+
int nColCuts = osicuts.sizeColCuts();
22+
if (nColCuts) {
23+
std::cout<<"There are "<<nColCuts<<" gomory column cuts! - converting"
24+
<<std::endl;
25+
// convert to row cut
26+
for (int i=0;i<nColCuts;i++) {
27+
const OsiColCut * cut = osicuts.colCutPtr(i);
28+
const CoinPackedVector lbs = cut->lbs();
29+
const CoinPackedVector ubs = cut->ubs();
30+
int ncols;
31+
const int * cols;
32+
const double * values;
33+
double one = -1.0;
34+
ncols = lbs.getNumElements();
35+
cols = lbs.getIndices();
36+
values = lbs.getElements();
37+
for (int j=0;j<ncols;j++) {
38+
int jColumn = cols[j];
39+
double value = values[j];
40+
// convert to <=
41+
OsiRowCut rc;
42+
rc.setRow(1,&jColumn,&one,false);
43+
rc.setLb(-COIN_DBL_MAX);
44+
rc.setUb(-value);
45+
osicuts.insertIfNotDuplicate(rc);
46+
}
47+
one = 1.0;
48+
ncols = ubs.getNumElements();
49+
cols = ubs.getIndices();
50+
values = ubs.getElements();
51+
for (int j=0;j<ncols;j++) {
52+
int jColumn = cols[j];
53+
double value = values[j];
54+
OsiRowCut rc;
55+
rc.setRow(1,&jColumn,&one,false);
56+
rc.setLb(-COIN_DBL_MAX);
57+
rc.setUb(value);
58+
osicuts.insertIfNotDuplicate(rc);
59+
}
60+
}
61+
}
62+
}
2063
//--------------------------------------------------------------------------
2164
// ** At present this does not use any solver
2265
void
@@ -531,6 +574,8 @@ CglGomoryUnitTest(
531574
/* objective,*/ colsol1,
532575
colLower, colUpper,
533576
rowLower, rowUpper, intVar, &warm);
577+
// new version may create a column cut if just one element
578+
convertColumnCuts(osicuts);
534579
nRowCuts = osicuts.sizeRowCuts();
535580
std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
536581
assert (nRowCuts==1);
@@ -742,6 +787,7 @@ CglGomoryUnitTest(
742787
/*objective,*/ colsol1,
743788
colLower, colUpper,
744789
rowLower, rowUpper, intVar, &warm);
790+
convertColumnCuts(osicuts);
745791
nRowCuts = osicuts.sizeRowCuts();
746792
std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
747793
assert (nRowCuts==1);
@@ -1234,6 +1280,7 @@ CglGomoryUnitTest(
12341280
/*objective,*/ colsol1,
12351281
colLower, colUpper,
12361282
rowLower, rowUpper, intVar, &warm);
1283+
convertColumnCuts(osicuts);
12371284
nRowCuts = osicuts.sizeRowCuts();
12381285
std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
12391286
assert (nRowCuts==1);
@@ -1367,6 +1414,7 @@ CglGomoryUnitTest(
13671414
/*objective,*/ colsol1,
13681415
colLower, colUpper,
13691416
rowLower, rowUpper, intVar, &warm);
1417+
convertColumnCuts(osicuts);
13701418
nRowCuts = osicuts.sizeRowCuts();
13711419
std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
13721420
assert (nRowCuts==1);

src/CglKnapsackCover/CglKnapsackCover.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "CoinSort.hpp"
1818
#include "CoinPackedMatrix.hpp"
1919
#include "OsiRowCutDebugger.hpp"
20-
#define GUBCOVER 1
20+
//#define GUBCOVER 1
2121
//#define PRINT_DEBUG
2222
//#define CGL_DEBUG 1
2323
//-----------------------------------------------------------------------------
@@ -70,7 +70,6 @@ void CglKnapsackCover::generateCuts(const OsiSolverInterface& si, OsiCuts& cs,
7070
// For each row point to vub variable
7171
// -1 if no vub
7272
// -2 if can skip row for knapsacks
73-
7473
int * vub = new int [nRows];
7574

7675
// Now vubValue are for positive coefficients and vlbValue for negative
@@ -3905,7 +3904,7 @@ CglKnapsackCover::createCliques( OsiSolverInterface & si,
39053904
}
39063905
}
39073906
int iUpper = upperValue > INT_MAX ? INT_MAX : static_cast<int> (floor(upperValue+1.0e-5));
3908-
int iLower = lowerValue < INT_MIN ? INT_MIN : static_cast<int> (ceil(lowerValue-1.0e-5));
3907+
int iLower = lowerValue < -INT_MIN ? -INT_MIN : static_cast<int> (ceil(lowerValue-1.0e-5));
39093908
int state=0;
39103909
if (upperValue<1.0e6) {
39113910
if (iUpper==1-numberM1)

src/CglPreProcess/CglPreProcess.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7098,6 +7098,10 @@ CglPreProcess::modified(OsiSolverInterface *model,
70987098
probingCut->setMaxProbeRoot(CoinMax(saveMaxProbe, 1000));
70997099
probingCut->setMaxElementsRoot(CoinMax(saveMaxElements, 2000));
71007100
int maxLook = CoinMin(numberColumns, numberRows)/2;
7101+
if ((options_&16)!=0) {
7102+
maxLook = numberColumns;
7103+
info.options |= 32768;
7104+
}
71017105
maxLook = CoinMin(maxLook,2000);
71027106
probingCut->setMaxLookRoot(CoinMax(saveMaxLook, maxLook));
71037107
options_ &= ~16;

0 commit comments

Comments
 (0)