15 #include "CbcModel.hpp"
16 #include "CbcBranchActual.hpp"
17 #include "CbcCutGenerator.hpp"
18 #include "CbcCompareActual.hpp"
19 #include "CbcCompareObjective.hpp"
20 #include "CbcCompareEstimate.hpp"
36 #define CUTOFF_TOL 1e-6
41 #include "CoinSignal.hpp"
54 if (interruptedOnce) {
55 std::cerr<<
"[BREAK]"<<std::endl;
59 std::cerr<<
"Ctrl+C detected, stopping Couenne..." << std::endl;
63 if (currentOA) currentOA -> parameter ().maxLocalSearchTime_ = 0.;
65 interruptedOnce =
true;
70 using namespace Couenne;
71 using namespace Bonmin;
89 OsiBabSolver * babInfo =
dynamic_cast<OsiBabSolver *
>(s.
continuousSolver()->getAuxiliaryInfo());
93 if (bonBabInfoPtr == NULL) {
107 model_.assignSolver(solver,
true);
116 model_.setSpecialOptions(specOpt);
121 model_.setStrategy(strat);
129 for (Bonmin::BabSetupBase::CuttingMethods::iterator i = s.
cutGenerators().begin() ;
135 model_.addCutGenerator(i->cgl,i->frequency,i->id.c_str(), i->normal,
139 ->setMustCallAgain(
true);
143 for (Bonmin::BabSetupBase::HeuristicMethods::iterator i = s.
heuristics().begin() ;
145 CbcHeuristic * heu = i->heuristic;
147 model_.addHeuristic(heu, i->id.c_str());
157 model_.solver()->messageHandler()->setLogLevel(logLevel);
161 bool ChangedObject =
false;
171 bool hasPseudo = (upPsCosts!=NULL);
172 model_.findIntegers(
true,hasPseudo);
173 OsiObject ** simpleIntegerObjects =
model_.objects();
174 int numberObjects =
model_.numberObjects();
175 if (priorities != NULL || directions != NULL || hasPseudo) {
176 ChangedObject =
true;
177 for (
int i = 0 ; i < numberObjects ; i++) {
178 CbcObject *
object =
dynamic_cast<CbcObject *
>
179 (simpleIntegerObjects[i]);
180 int iCol =
object->columnNumber();
182 object->setPriority(priorities[iCol]);
184 object->setPreferredWay(directions[iCol]);
186 CbcSimpleIntegerPseudoCost * pscObject =
187 dynamic_cast<CbcSimpleIntegerPseudoCost*
> (object);
188 pscObject->setUpPseudoCost(upPsCosts[iCol]);
189 pscObject->setDownPseudoCost(downPsCosts[iCol]);
203 const int & numSos = sos->
num;
204 (*nlpSolver->messageHandler())<<
"Adding "<<sos->
num<<
" sos constraints."
207 CbcObject ** objects =
new CbcObject*[numSos];
208 const int * starts = sos->
starts;
209 const int * indices = sos->
indices;
210 const char * types = sos->
types;
211 const double * weights = sos->
weights;
213 bool hasPriorities =
false;
215 int numberObjects =
model_.numberObjects();
218 for (
int i = 0 ; i < numberObjects ; i++) {
219 if (varPriorities[i]) {
220 hasPriorities =
true;
228 for (
int i = 0 ; i < numSos ; i++) {
229 if (sosPriorities[i]) {
230 hasPriorities =
true;
235 for (
int i = 0 ; i < numSos ; i++)
237 int start = starts[i];
238 int length = starts[i + 1] - start;
240 printf(
"setting nway object\n"),
241 objects[i] =
new CbcNWay(&
model_, length, &indices[start],
243 objects[i]->setPriority(1);
245 objects[i] =
new CbcSOS(&
model_, length, &indices[start],
246 &weights[start], i, types[i]);
247 objects[i]->setPriority(10);
249 if (hasPriorities && sosPriorities && sosPriorities[i]) {
250 objects[i]->setPriority(sosPriorities[i]);
253 model_.addObjects (numSos, objects);
254 for (
int i = 0 ; i < numSos ; i++)
261 CbcObject ** objects =
new CbcObject *[s.
objects().size()];
262 for (
unsigned int i = 0 ; i < s.
objects().size() ; i++) {
263 objects[i] =
dynamic_cast<CbcObject *
> (s.
objects()[i]);
265 objects[i]->setModel(&
model_);
287 CbcBranchDefaultDecision branch;
294 model_.setBranchingMethod(&branch);
296 model_.solver()->deleteObjects();
309 CbcCompareObjective compare;
310 model_.setNodeComparison(compare);
313 CbcCompareDepth compare;
314 model_.setNodeComparison(compare);
317 CbcCompareDefault compare;
318 compare.setWeight(0.0);
319 model_.setNodeComparison(compare);
322 CbcCompareDefault compare;
323 model_.setNodeComparison(compare);
328 CbcCompareEstimate compare;
329 model_.setNodeComparison(compare);
331 model_.addHeuristic(guessHeu);
341 model_.passInTreeHandler(treeTraversal);
346 model_.passInTreeHandler(treeTraversal);
351 model_.passInTreeHandler(treeTraversal);
356 model_.passInTreeHandler(treeTraversal);
364 model_.setNodeComparison(compare);
369 model_.setNumberPenalties(8);
383 OsiObject ** objects =
model_.objects();
385 if (specOpt!=16 && objects) {
387 int numberObjects =
model_.numberObjects();
393 objects_ =
new OsiObject*[numberObjects];
395 for (
int i = 0 ; i < numberObjects; i++) {
396 OsiObject * obj = objects[i];
397 CbcSimpleInteger * intObj =
dynamic_cast<CbcSimpleInteger *
> (obj);
402 CbcSOS * sosObj =
dynamic_cast<CbcSOS *
>(obj);
405 CbcObject * cbcObj =
dynamic_cast<CbcObject *
>(obj);
407 std::cerr<<
"Unsupported CbcObject appears in the code"<<std::endl;
416 CbcCutGenerator ** gen =
model_.cutGenerators();
417 int numGen =
model_.numberCutGenerators();
418 for (
int i = 0 ; i < numGen ; i++) {
465 s.
options()->GetEnumValue(
"enable_dynamic_nlp", ival,
"bonmin.");
469 if(!
model_.solver()->isProvenOptimal() ){
481 std::vector<const OsiRowCut *> mycuts(cuts.sizeRowCuts());
482 for(
int i = 0 ; i < cuts.sizeRowCuts() ; i++){
483 mycuts[i] = cuts.rowCutPtr(i);
485 model_. solver () -> applyRowCuts ((
int) mycuts.size(), (
const OsiRowCut **) &mycuts[0]);
493 model_.solver()->resolve();
497 model_.passInSolverCharacteristics (bonBabInfoPtr);
503 const double * colsol =
model_.solver()->getColSolution();
504 const double * duals =
model_.solver()->getRowPrice();
509 model_.solver()->setColSolution(colsol);
510 model_.solver()->setRowPrice(duals);
519 #if 0 // Sometimes primal dual point is problematic in the context of Cut-and-branch
520 model_.solver()->resolve();
521 if(!
model_.solver()->isProvenOptimal())
522 model_.solver()->setColSolution(NULL);
527 CoinSighandler_t saveSignal = SIG_DFL;
536 remaining_time -= CoinCpuTime();
537 model_.setDblParam(CbcModel::CbcMaximumSeconds, remaining_time);
538 if(remaining_time > 0.)
544 (TMINLP::MINLP_ERROR, 0, NULL, DBL_MAX);
553 bool hasFailed =
false;
568 int numberGenerators =
model_.numberCutGenerators();
569 for (
int iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
570 CbcCutGenerator * generator =
model_.cutGenerator(iGenerator);
572 if (
true&&!(generator->numberCutsInTotal() || generator->numberColumnCuts()))
576 <<
"was tried" << generator->numberTimesEntered()
577 <<
"times and created" << generator->numberCutsInTotal()+generator->numberColumnCuts()
578 <<
"cuts of which" << generator->numberCutsActive()
579 <<
"were active after adding rounds of cuts";
593 if (
model_.numberObjects()==0) {
596 OsiSolverInterface * solver =
600 CoinCopyN(solver->getColSolution(), solver->getNumCols(),
613 (*s.
nonlinearSolver()->messageHandler())<<
"\nReal objective function: "
614 <<bestObj_<<CoinMessageEol;
616 else if (
model_.bestSolution()) {
622 if(remaining_time <= 0.){
623 status = TMINLP::LIMIT_EXCEEDED;
631 else if (
model_.status() == 0) {
632 if(
model_.isContinuousUnbounded()){
633 status = TMINLP::CONTINUOUS_UNBOUNDED;
638 status = TMINLP::SUCCESS;
642 status = TMINLP::INFEASIBLE;
646 else if (
model_.status() == 1 ||
model_.status() == 5) {
647 #if (BONMIN_VERSION_MAJOR > 1) || (BONMIN_VERSION_MINOR > 6)
648 status =
model_.status() == 1 ? TMINLP::LIMIT_EXCEEDED : TMINLP::USER_INTERRUPT;
650 status = TMINLP::LIMIT_EXCEEDED;
659 else if (
model_.status()==2) {
660 status = TMINLP::MINLP_ERROR;
666 !(
problem_ -> getRecordBestSol ()) ||
667 !(
problem_ -> getRecordBestSol () -> getHasSol()) ||
672 assert(use_RBS_Cbc ||
problem_ -> getRecordBestSol () -> getSol() != NULL);
683 !(
problem_ -> getRecordBestSol ()) ||
684 !(
problem_ -> getRecordBestSol () -> getHasSol()) ||
688 return problem_ -> getRecordBestSol () -> getSol ();
693 !(
problem_ -> getRecordBestSol ()) ||
694 !(
problem_ -> getRecordBestSol () -> getHasSol()) ||
698 return problem_ -> getRecordBestSol () -> getVal ();
int getIntParameter(const IntParameter &p) const
Return value of integer parameter.
Behavior of the algorithm in the case of a failure.
int nObjects_
number of objects.
double bestObj_
objValue of MIP
Max number of failures in a branch.
static bool interruptedOnce
void initialize(BabSetupBase &b)
Initialize the method (get options)
Ipopt::SmartPtr< TMINLP > tminlp()
return pointer to tminlp_.
void setCbcModel(CbcModel *cbc_model)
Method for setting CbcModel, which is used to get statusOfSearch.
const vector< OsiObject * > & objects() const
Access to extra objects.
double getNewCutoffDecr()
Are there a numerical difficulties?
void setObjects(OsiObject **objects, int nObjects)
Set objects.
void initialize(BabSetupBase &b)
Initialize the method (get options)
const double * bestSolution() const
Get the best solution known to the problem (is optimal if MipStatus is FeasibleOptimal).
int mipIterationCount_
get total number of iterations in last mip solved.
const double * getDownPsCosts() const
Get number of columns.
This class chooses a variable to branch on.
int num
Number of SOS constraints.
CoinMessageHandler * modelHandler_
Message handler for CbcModel.
MipStatuses mipStatus_
Status of the mip solved.
static void couenne_signal_handler(int whichSignal)
const TMINLP2TNLP * problem() const
get pointer to the TMINLP2TNLP adapter
const double * getUpPsCosts() const
Get number of columns.
This is class provides an Osi interface for a Mixed Integer Linear Program expressed as a TMINLP (so ...
Stop if relative gap is less than this.
virtual const SosInfo * sosConstraints() const =0
int has_x_init()
xInit has been set?
Spetial option in particular for Cbc.
Same as DfsDiveFromBest, but after a prescribed number of integer solution are found switch to best-b...
virtual ~CouenneBab()
Destructor.
There is a CbcObject in the model which is not understood by Bonmin.
void setComparisonBound(const CbcCompareBase &val)
Set comparison method when closing bound.
void initialize(BabSetupBase &b)
Initialize the method (get options)
double * bestSolution_
Stores the solution of MIP.
Number of candidates for strong branching.
CbcModel model_
CbcModel used to solve problem.
Class to store sos constraints for model.
double continuousRelaxation_
Continuous relaxation of the problem.
void generateCuts(const OsiSolverInterface &solver, OsiCuts &cs, const CglTreeInfo info=CglTreeInfo())
int numNodes_
Number of nodes enumerated.
const int * getBranchingDirections() const
get prefered branching directions
const std::vector< double > & bestSolution2() const
get the best solution computed with alternative objective function.
virtual int getNumCols() const
Get number of columns.
void setup_global_time_limit(double time_limit)
Setup for a global time limit for solver.
const int * getPriorities() const
Get priorities on integer variables.
void setDiver(CbcDfsDiver *diver)
Set the dfs diver to use.
Dynamic strategy, see CbcBranchActual.hpp for explanations.
Minimum reliability before trust pseudo-costs.
From a TMINLP, this class adapts to another TMINLP where the original objective is transformed into a...
const Bonmin::TNLPSolver * solver() const
TreeTraversal treeTraversalMethod()
Method used to traverse tree.
virtual void replaceIntegers(OsiObject **objects, int numberObjects)
virtual callback function to eventually modify objects for integer variable (replace with user set)...
Class to perform OA in its classical form.
int * starts
For 0 <= i < nums, start[i] gives the indice of indices and weights arrays at which the description o...
void assignLpInterface(OsiSolverInterface *si)
Assign an OsiTMINLPInterface.
A class to have all elements necessary to setup a branch-and-bound.
limit on number of integer feasible solution.
CouenneProblem * problem_
virtual void finalize_solution(TMINLP::SolverReturn status, Ipopt::Index n, const Ipopt::Number *x, Ipopt::Number obj_value)=0
This method is called when the algorithm is complete so the TNLP can store/write the solution...
SolverReturn
Return statuses of algorithm.
virtual bool setWarmStart(const CoinWarmStart *warm, Ipopt::SmartPtr< TMINLP2TNLP > tnlp)=0
Set the warm start in the solver.
virtual void branchAndBound(Bonmin::BabSetupBase &s)
Carry out branch and bound.
Problem has been proven to be infeasible.
bool hasContinuedOnAFailure()
Did we continue on a failure.
double bestObj() const
Return objective value of the bestSolution.
A more elaborate diving class.
Class for MINLP problems with symbolic information.
static CbcModel * currentBranchModel
OsiChooseVariable * branchingMethod()
branching method to use.
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real * s
int * priorities
priorities of sos constraints.
double bestObj2() const
return objective value of the best solution computed with alternative objective function.
Display information every logIntervval nodes.
Max number of consecutive infeasible problem in a branch before fathoming.
dive from top node of the heap untill it gets to a leaf of the tree.
void forceSolverOutput(int log_level)
Bonmin::OACutGenerator2 * currentOA
void setProblem(CouenneProblem *p)
Consider or not SOS constraints.
Log level for root relaxation.
NodeComparison & nodeComparisonMethod()
Method used to compare nodes.
double bestBound_
best known (lower) bound.
void setModel(Ipopt::SmartPtr< TMINLP > tminlp)
Set the model to be solved by interface.
void setBabPtr(Bab *babPtr)
Set pointer to the branch-and-bound algorithm (to access CbcModel).
Number of cut passes at nodes.
int * indices
indices of elements belonging to the SOS.
virtual CoinWarmStart * getWarmStart(Ipopt::SmartPtr< TMINLP2TNLP > tnlp) const =0
Get the warm start form the solver.
const TMINLP * model() const
void initialize(BabSetupBase &s)
We will throw this error when a problem is not solved.
An integer solution to the problem has been found.
OsiTMINLPInterface * nonlinearSolver()
Pointer to the non-linear solver used.
Ipopt::SmartPtr< Ipopt::OptionsList > options()
Acces list of Options.
double getDoubleParameter(const DoubleParameter &p) const
Return value of double parameter.
No feasible solution to the problem is known.
Optimum solution has been found and its optimality proved.
OsiSolverInterface * continuousSolver()
Pointer to the continuous solver to use for relaxations.
Base class for OA algorithms.
HeuristicMethods & heuristics()
list of Heuristic methods to use.
dive from top node of the heap with more elaborate strategy (see options doc).
Eplore two kids before following on dive.
Number of cut passes at nodes.
Class to do probed diving in the tree.
void setComparisonDive(const CbcCompareBase &val)
Set comparison method when diving.
OsiObject ** objects_
OsiObjects of the model.
CuttingMethods & cutGenerators()
list of cutting planes methods to apply with their frequencies.
Class to do diving in the tree.
void setSolverOutputToDefault()
const CbcModel & model() const
Get cbc model used to solve.
Stop if absolute gap is less than this.
Best guessed integer solution is subtree below, based on pseudo costs.
Bonmin class for passing info between components of branch-and-cuts.
double * weights
weights of the elements of the SOS.