[Cbc] CBC 2.9 vs. 2.8, presolving
Christoph Cullmann
cullmann at absint.com
Mon Feb 2 03:14:12 EST 2015
Hi,
using the example:
http://www.absint.com/dla/lpsolve/value_9041131.lp.gz
and a solver like below that mail, now the presolving no longer
terminates in any reasonable time (e.g. > 20 minutes here instead of seconds with CBC 2.8).
Is this a regression or just some API misuse?
Greetings
Christoph
bool solveLP (const char *infile)
{
/**
* liberror message handler
*/
ClpsolveMessageHandler messageHandler;
/**
* load problem from lp file, else die
*/
Ur::printf (Ur::Progress, "Reading lp file '%s'...", infile);
OsiClpSolverInterface solver;
setLpOptions (&solver, messageHandler);
if (solver.readLp(infile)) {
Ur::printf (Ur::Error, "Cannot open '%s', CPLEX LP file processing error.", infile);
return false;
}
Ur::printf (Ur::Progress, "Finished reading lp file.");
/**
* some stats
*/
Ur::printf (Ur::Note,
"Statistics:\n"
"Number of columns: %d.\n"
"Number of rows: %d.\n"
"Number of non-zero elements: %d.\n",
solver.getNumCols(),
solver.getNumRows(),
solver.getNumElements());
double time1 = CoinCpuTime();
double time2 = time1;
/**
* initial solve parameters
*/
ClpSolve solvectl;
// Tell code to return at once if infeasible
solvectl.setInfeasibleReturn(true);
// make sure uses dual
solvectl.setSolveType(ClpSolve::useDual);
/**
* fast initial solve
*/
ClpSimplex *simplex = solver.getModelPtr();
// deactivate scaling
simplex->scaling(0);
solver.setHintParam(OsiDoScale,false,OsiHintDo);
// Set perturbation on
simplex->setPerturbation(50);
if (simplex->initialSolve(solvectl) == -1 || !simplex->isProvenOptimal()) {
if (simplex->problemStatus()==1)
handleNoResult (solver, "This problem is infeasible", Ur::MessageNumber::ILPSolving::InfeasibleOrUnboundedProblem);
else
handleNoResult (solver, "This problem is unbounded", Ur::MessageNumber::ILPSolving::InfeasibleOrUnboundedProblem);
return true;
}
// make sure basis correct in solver
solver.setWarmStart(NULL);
// below not needed - just making sure for now
solver.initialSolve();
// Change infeasibility weight if large objective
if (fabs(simplex->objectiveValue() + simplex->objectiveOffset()) > 1.0e10) {
simplex->setInfeasibilityCost(1000.0 * simplex->infeasibilityCost());
}
// find largest value
{
const double *solution = solver.getColSolution();
int numberColumns = solver.getNumCols();
double largest = 0.0;
for (int i = 0; i < numberColumns; i++)
largest = CoinMax(largest, solution[i]);
simplex->setDualBound(CoinMin(simplex->dualBound(), 1.01 * largest + 1.0));
}
/**
* Create CglPreProcessor
*/
CglPreProcess process;
process.passInMessageHandler (&messageHandler);
/**
* do pre process
*/
OsiSolverInterface *preprocessedSolver = process.preProcess (solver);
time2 = CoinCpuTime();
if (!preprocessedSolver) {
handleNoResult (solver, "This problem is infeasible", Ur::MessageNumber::ILPSolving::InfeasibleOrUnboundedProblem);
return true;
}
/**
* some stats
*/
Ur::printf (Ur::Note,
"Statistics (after preprocessing):\n"
"Number of columns: %d.\n"
"Number of rows: %d.\n"
"Number of non-zero elements: %d.\n",
preprocessedSolver->getNumCols(),
preprocessedSolver->getNumRows(),
preprocessedSolver->getNumElements());
/**
* resolve
*/
setLpOptions (preprocessedSolver, messageHandler);
preprocessedSolver->resolve();
/**
* Cbc model creation
*/
CbcModel model (*preprocessedSolver);
model.passInMessageHandler (&messageHandler);
/**
* add some defaults
*/
CbcMain0 (model);
/**
* solve
*/
model.branchAndBound();
if (model.isProvenOptimal()) {
// Good
} else if (model.isProvenInfeasible()) {
handleNoResult (solver, "This problem is infeasible", Ur::MessageNumber::ILPSolving::InfeasibleOrUnboundedProblem);
return true;
} else {
// some error
Ur::printf (Ur::Error, "No optimal solution found, solving failed.");
return false;
}
process.postProcess(*model.solver());
// look at solution
const double *solution = solver.getColSolution();
int numberColumns = solver.getNumCols();
int iColumn;
// double check
const double *lower = solver.getColLower();
const double *upper = solver.getColUpper();
int numberIntegers = 0;
for (iColumn = 0; iColumn < numberColumns; iColumn++) {
double value = floor(solution[iColumn] + 0.5);
if (solver.isInteger(iColumn)) {
solver.setColLower(iColumn, CoinMax(value, lower[iColumn]));
solver.setColUpper(iColumn, CoinMin(value, upper[iColumn]));
numberIntegers++;
}
}
if (numberIntegers < numberColumns) {
solver.resolve();
} else {
// just setup so will do checks
solver.getModelPtr()->setProblemStatus(1);
}
// Use relaxed criterion
solver.getModelPtr()->checkUnscaledSolution();
if (!solver.isProvenOptimal()) {
// bug
Ur::printf (Ur::Error, "No optimal solution found, solving failed.");
return false;
}
// objective value
outputObjectiveValue ((solver.getObjValue () < 0) ? -solver.getObjValue () : solver.getObjValue ());
/* column values... */
for (iColumn = 0; iColumn < numberColumns; iColumn++)
outputColumnValue (iColumn, solver.getColName(iColumn).c_str(), solution[iColumn]);
// be done
return true;
}
--
----------------------------- Dr.-Ing. Christoph Cullmann ---------
AbsInt Angewandte Informatik GmbH Email: cullmann at AbsInt.com
Science Park 1 Tel: +49-681-38360-22
66123 Saarbrücken Fax: +49-681-38360-20
GERMANY WWW: http://www.AbsInt.com
--------------------------------------------------------------------
Geschäftsführung: Dr.-Ing. Christian Ferdinand
Eingetragen im Handelsregister des Amtsgerichts Saarbrücken, HRB 11234
More information about the Cbc
mailing list