Skip to content

Commit

Permalink
Add a way to use the presolver papilo, which is a free presolver from…
Browse files Browse the repository at this point in the history
… the SCIP project. Not much work has been done recently in Coin on pre-processing for integer problems and this does well on some problems. To use see instructions at end of CglPreProcess.cpp and add -DCBC_USE_PAPILO=1 to build of Cbc.
  • Loading branch information
jjhforrest committed Sep 10, 2024
1 parent f657200 commit 729e751
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 3 deletions.
13 changes: 12 additions & 1 deletion src/CbcParameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1271,9 +1271,20 @@ void CbcParameters::addCbcSolverKwdParams() {
parameters_[CbcParam::PREPROCESS]->appendKwd("strategy", CbcParameters::IPPStrategy);
parameters_[CbcParam::PREPROCESS]->appendKwd("aggregate", CbcParameters::IPPAggregate);
parameters_[CbcParam::PREPROCESS]->appendKwd("forcesos", CbcParameters::IPPForceSOS);
#if CBC_USE_PAPILO
parameters_[CbcParam::PREPROCESS]->appendKwd("papilob!egin", CbcParameters::IPPPapilo);
parameters_[CbcParam::PREPROCESS]->appendKwd("papilo2b!egin", CbcParameters::IPPPapilo2);
parameters_[CbcParam::PREPROCESS]->appendKwd("papilo", CbcParameters::IPPPapiloEnd);
parameters_[CbcParam::PREPROCESS]->appendKwd("papilo2", CbcParameters::IPPPapilo2End);
#endif
parameters_[CbcParam::PREPROCESS]->appendKwd("stop!aftersaving", CbcParameters::IPPStopAfterSaving);
parameters_[CbcParam::PREPROCESS]->appendKwd("equalallstop", CbcParameters::IPPEqualAllStop);

#if CBC_USE_PAPILO
parameters_[CbcParam::PREPROCESS]->appendKwd("papilobeginstop", CbcParameters::IPPPapiloStop);
parameters_[CbcParam::PREPROCESS]->appendKwd("papilo2beginstop", CbcParameters::IPPPapilo2Stop);
parameters_[CbcParam::PREPROCESS]->appendKwd("papilostop", CbcParameters::IPPPapiloStopEnd);
parameters_[CbcParam::PREPROCESS]->appendKwd("papilo2stop", CbcParameters::IPPPapilo2StopEnd);
#endif
parameters_[CbcParam::SOSPRIORITIZE]->setup(
"sosP!rioritize", "How to deal with SOS priorities",
"This sets priorities for SOS. Values 'high' and 'low' just set a "
Expand Down
10 changes: 10 additions & 0 deletions src/CbcParameters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,16 @@ class CBCLIB_EXPORT CbcParameters {
IPPForceSOS,
IPPStopAfterSaving,
IPPEqualAllStop,
#if CBC_USE_PAPILO
IPPPapilo,
IPPPapilo2,
IPPPapiloEnd,
IPPPapilo2End,
IPPPapiloStop,
IPPPapilo2Stop,
IPPPapiloStopEnd,
IPPPapilo2StopEnd,
#endif
IPPEndMarker
};

Expand Down
74 changes: 72 additions & 2 deletions src/CbcSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1430,7 +1430,7 @@ int CbcMain1(std::deque<std::string> inputQueue, CbcModel &model,
int redsplit2Mode = CbcParameters::CGOff;
assert (parameters[CbcParam::REDSPLIT2CUTS]->modeVal()==redsplit2Mode);

CglGMI GMIGen;
CglGMI GMIGen;
int GMIMode = parameters[CbcParam::GMICUTS]->modeVal();

std::string cgraphMode = "on";
Expand Down Expand Up @@ -4827,9 +4827,73 @@ int CbcMain1(std::deque<std::string> inputQueue, CbcModel &model,
if (keepPPN)
babModel_->setKeepNamesPreproc(1);
setPreProcessingMode(saveSolver,1);
#if CBC_USE_PAPILO
extern void zapPapilo(int pOptions,CglPreProcess * process);
int pOptions = 0;
int tune2 = preProcess;
// Convert to minimize if papilo
bool maximize = false;
if (tune2>11) {
OsiClpSolverInterface * clpSolver =
dynamic_cast<OsiClpSolverInterface *>(saveSolver);
if (clpSolver->getObjSense()==-1.0) {
maximize = true;
clpSolver->setObjSense(1.0);
double objOffset;
clpSolver->getDblParam(OsiObjOffset, objOffset);
int numberColumns = clpSolver->getNumCols();
double * objective = clpSolver->getModelPtr()->objective();
for (int i=0;i<numberColumns;i++)
objective[i] = -objective[i];
clpSolver->setDblParam(OsiObjOffset, -objOffset);
}
bool stopAfter = false;
if (tune2>15) {
preProcess=10; // say stop
tune2 -=4;
} else {
preProcess=1;
}
#ifdef CBC_THREAD
pOptions = (tune2&1) != 0 ? 2 : 0; // bug when 1???
#endif
if ((tune2&2) == 0)
pOptions|= 8; // at beginning
else
pOptions|= 16; // at end
}
zapPapilo(pOptions,&process);
#endif
solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses,
tunePreProcess);
setPreProcessingMode(saveSolver,0);
setPreProcessingMode(saveSolver,0);
#if CBC_USE_PAPILO
// Convert back
if (maximize) {
OsiClpSolverInterface * clpSolver =
dynamic_cast<OsiClpSolverInterface *>(saveSolver);
double objOffset;
clpSolver->setObjSense(-1.0);
clpSolver->getDblParam(OsiObjOffset, objOffset);
int numberColumns = clpSolver->getNumCols();
double * objective = clpSolver->getModelPtr()->objective();
for (int i=0;i<numberColumns;i++)
objective[i] = -objective[i];
clpSolver->setDblParam(OsiObjOffset, -objOffset);
if (solver2) {
OsiClpSolverInterface * clpSolver =
dynamic_cast<OsiClpSolverInterface *>(solver2);
double objOffset;
clpSolver->setObjSense(-1.0);
clpSolver->getDblParam(OsiObjOffset, objOffset);
int numberColumns = clpSolver->getNumCols();
double * objective = clpSolver->getModelPtr()->objective();
for (int i=0;i<numberColumns;i++)
objective[i] = -objective[i];
clpSolver->setDblParam(OsiObjOffset, -objOffset);
}
}
#endif
if (solver2) {
setPreProcessingMode(solver2, 0);
model_.setOriginalColumns(process.originalColumns(),
Expand Down Expand Up @@ -7722,6 +7786,12 @@ int CbcMain1(std::deque<std::string> inputQueue, CbcModel &model,
#ifdef CBC_THREAD
int numberThreads = parameters[CbcParam::THREADS]->intVal();
babModel_->setNumberThreads(numberThreads % 100);
// switch off deterministic if large problem and fastNodeDepth>0
if (numberThreads/100==2) {
numberThreads -= 100;
if (babModel_->fastNodeDepth()>0 && babModel_->solver()->getNumRows()>2000)
babModel_->setFastNodeDepth(-999);
}
babModel_->setThreadMode((numberThreads%1000) / 100);
#ifdef CBC_USE_OPENMP
if (numberThreads>100) {
Expand Down

0 comments on commit 729e751

Please sign in to comment.