/* Generate cuts for the model data contained in si. The generated cuts are inserted into and returned in the collection of cuts cs. */ bool AbcCutGenerator::generateCuts( OsiCuts & cs , bool fullScan) { int howOften = whenCutGenerator_; if (howOften == -100) return false; if (howOften > 0) howOften = howOften % 1000000; else howOften = 1; if (!howOften) howOften = 1; bool returnCode = false; OsiSolverInterface * solver = model_->solver(); #if defined(ABC_DEBUG_MORE) std::cout << "model_->getNodeCount() = " << model_->getNodeCount() << std::endl; #endif if (fullScan || (model_->getNodeCount() % howOften) == 0 ) { CglProbing* generator = dynamic_cast<CglProbing*>(generator_); if (!generator) { generator_->generateCuts(*solver,cs); } else { // Probing - return tight column bounds CglTreeInfo info; generator->generateCutsAndModify(*solver,cs,&info); const double * tightLower = generator->tightLower(); const double * lower = solver->getColLower(); const double * tightUpper = generator->tightUpper(); const double * upper = solver->getColUpper(); const double * solution = solver->getColSolution(); int j; int numberColumns = solver->getNumCols(); double primalTolerance = 1.0e-8; for (j=0; j<numberColumns; j++) { if (tightUpper[j] == tightLower[j] && upper[j] > lower[j]) { // fix solver->setColLower(j, tightLower[j]); solver->setColUpper(j, tightUpper[j]); if (tightLower[j] > solution[j] + primalTolerance || tightUpper[j] < solution[j] - primalTolerance) returnCode = true; } } } } return returnCode; }
bool BlisConGenerator::generateCons(OsiCuts & coinCuts , bool fullScan) { bool status = false; if (strategy_ == -2) { // This con generator has been disabled. return false; } OsiSolverInterface * solver = model_->solver(); #if defined(BLIS_DEBUG_MORE) std::cout << "model_->getNodeCount() = " << model_->getNodeCount() << std::endl; #endif if ( fullScan || ((strategy_ > 0) && (model_->getNumNodes() % strategy_) == 0) ) { //-------------------------------------------------- // Start to generate cons ... //-------------------------------------------------- int j; double start = CoinCpuTime(); int numConsBefore = coinCuts.sizeCuts(); int numRowsBefore = coinCuts.sizeRowCuts(); assert(generator_ != NULL); CglProbing* generator = dynamic_cast<CglProbing *>(generator_); if (!generator) { generator_->generateCuts(*solver, coinCuts); } else { // It is probing - return tight column bound CglTreeInfo info; generator->generateCutsAndModify(*solver, coinCuts, &info); const double * tightLower = generator->tightLower(); const double * lower = solver->getColLower(); const double * tightUpper = generator->tightUpper(); const double * upper = solver->getColUpper(); const double * solution = solver->getColSolution(); int numberColumns = solver->getNumCols(); double primalTolerance = 1.0e-8; for (j = 0; j < numberColumns; ++j) { if ( (tightUpper[j] == tightLower[j]) && (upper[j] > lower[j]) ) { // fix column j solver->setColLower(j, tightLower[j]); solver->setColUpper(j, tightUpper[j]); if ( (tightLower[j] > solution[j] + primalTolerance) || (tightUpper[j] < solution[j] - primalTolerance) ) { status = true; } } } } // EOF probing. //-------------------------------------------------- // Remove zero length row cuts. //-------------------------------------------------- int numRowCons = coinCuts.sizeRowCuts(); for (j = numRowsBefore; j < numRowCons; ++j) { OsiRowCut & rCut = coinCuts.rowCut(j); int len = rCut.row().getNumElements(); #ifdef BLIS_DEBUG_MORE std::cout << "Cut " << j<<": length = " << len << std::endl; #endif if (len == 0) { // Empty cuts coinCuts.eraseRowCut(j); --j; --numRowCons; #ifdef BLIS_DEBUG std::cout << "WARNING: Empty cut from " << name_ << std::endl; #endif } else if (len < 0) { #ifdef BLIS_DEBUG std::cout << "ERROR: Cut length = " << len << std::endl; #endif // Error assert(0); } } //-------------------------------------------------- // Update statistics. //-------------------------------------------------- ++calls_; numConsGenerated_ += (coinCuts.sizeCuts() - numConsBefore); time_ += (CoinCpuTime() - start); if (numConsGenerated_ == 0) { ++noConsCalls_; } } return status; }
// Generate constraints for the model data contained in si. // The generated constraints are inserted into and returned in the // constraint pool. // Default implementation use Cgl cut generators. bool BlisConGenerator::generateConstraints(BcpsConstraintPool &conPool) { bool status = false; OsiSolverInterface * solver = model_->solver(); #if defined(BLIS_DEBUG_MORE) std::cout << "model_->getNodeCount() = " << model_->getNodeCount() << std::endl; #endif //-------------------------------------------------- // Start to generate constraints... //-------------------------------------------------- assert(generator_ != NULL); int j; OsiCuts newOsiCuts; CglProbing* generator = dynamic_cast<CglProbing *>(generator_); if (generator) { // It is CglProbing - return tight column bounds CglTreeInfo info; generator->generateCutsAndModify(*solver, newOsiCuts, &info); const double * tightLower = generator->tightLower(); const double * lower = solver->getColLower(); const double * tightUpper = generator->tightUpper(); const double * upper = solver->getColUpper(); const double * solution = solver->getColSolution(); int numberColumns = solver->getNumCols(); double primalTolerance = 1.0e-8; for (j = 0; j < numberColumns; ++j) { if ( (tightUpper[j] == tightLower[j]) && (upper[j] > lower[j]) ) { // Fix column j solver->setColLower(j, tightLower[j]); solver->setColUpper(j, tightUpper[j]); if ( (tightLower[j] > solution[j] + primalTolerance) || (tightUpper[j] < solution[j] - primalTolerance) ) { status = true; } } } } else { // Other Cgl cut generators generator_->generateCuts(*solver, newOsiCuts); } //-------------------------------------------------- // Create blis constraints and remove zero length row cuts. //-------------------------------------------------- int numNewConstraints = newOsiCuts.sizeRowCuts(); for (j = 0; j < numNewConstraints; ++j) { OsiRowCut & rCut = newOsiCuts.rowCut(j); int len = rCut.row().getNumElements(); #ifdef BLIS_DEBUG_MORE std::cout << "Cut " << j<<": length = " << len << std::endl; #endif if (len > 0) { // Create BlisConstraints from OsiCuts. BlisConstraint *blisCon = BlisOsiCutToConstraint(&rCut); conPool.addConstraint(blisCon); } else if (len == 0) { // Empty cuts #ifdef BLIS_DEBUG std::cout << "WARNING: Empty cut from " << name_ << std::endl; #endif } else { #ifdef BLIS_DEBUG std::cout << "ERROR: Cut length = " << len << std::endl; #endif // Error assert(0); } } // Adjust cut strategy. if ( (strategy_ == BlisCutStrategyAuto) && (noConsCalls_ > BLIS_CUT_DISABLE) ) { strategy_ = BlisCutStrategyNone; } return status; }