[Cbc] CBC 2.9 vs. 2.8, presolving

John Forrest john.forrest at fastercoin.com
Mon Feb 2 03:43:02 EST 2015


Christoph,

Stand-alone solver solves immediately.  Some preprocessing was made a 
bit stronger - so that may be it.

I will get back to you when I have managed to compile your driver.

John


On 02/02/15 08:14, Christoph Cullmann wrote:
> 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;
> }
>
>



More information about the Cbc mailing list