00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #if defined(_MSC_VER)
00013
00014 # pragma warning(disable:4786)
00015 #endif
00016 #include <string>
00017 #include <cassert>
00018 #include <cfloat>
00019 #include "OsiSolverInterface.hpp"
00020 #include "CoinWarmStartBasis.hpp"
00021 #include "CbcModel.hpp"
00022 #include "BonCbcNode.hpp"
00023 #include "BonOsiTMINLPInterface.hpp"
00024 #include "BonIpoptWarmStart.hpp"
00025 #include "BonOsiTMINLPInterface.hpp"
00026
00027 using namespace std;
00028
00029
00030 namespace Bonmin
00031 {
00032
00033 BonCbcFullNodeInfo::BonCbcFullNodeInfo()
00034 :
00035 CbcFullNodeInfo(),
00036 sequenceOfInfeasiblesSize_(0),
00037 sequenceOfUnsolvedSize_(0)
00038 {}
00039
00040 BonCbcFullNodeInfo::BonCbcFullNodeInfo(CbcModel * model,
00041 int numberRowsAtContinuous) :
00042 CbcFullNodeInfo(model, numberRowsAtContinuous),
00043 sequenceOfInfeasiblesSize_(0),
00044 sequenceOfUnsolvedSize_(0)
00045 {}
00046
00047
00048 BonCbcFullNodeInfo::BonCbcFullNodeInfo ( const BonCbcFullNodeInfo &other):
00049 CbcFullNodeInfo(other),
00050 sequenceOfInfeasiblesSize_(other.sequenceOfInfeasiblesSize_),
00051 sequenceOfUnsolvedSize_(other.sequenceOfUnsolvedSize_)
00052
00053 {}
00054
00055
00056 void
00057 BonCbcFullNodeInfo::allBranchesGone()
00058 {
00059 IpoptWarmStart * ipws = dynamic_cast<IpoptWarmStart *>(basis_);
00060 if (ipws)
00061 ipws->flushPoint();
00062 }
00063
00064 BonCbcFullNodeInfo::~BonCbcFullNodeInfo()
00065 {}
00066
00067 CbcNodeInfo *
00068 BonCbcFullNodeInfo::clone() const
00069 {
00070 return new BonCbcFullNodeInfo(*this);
00071 }
00072
00073 void
00074 BonCbcFullNodeInfo::registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
00075 {
00076
00077
00078 roptions->SetRegisteringCategory("Options for non-convex problems", RegisteredOptions::BonminCategory);
00079 roptions->AddLowerBoundedIntegerOption("max_consecutive_infeasible",
00080 "Number of consecutive infeasible subproblems before aborting a"
00081 " branch.",
00082 0,0,
00083 "Will continue exploring a branch of the tree until \"max_consecutive_infeasible\""
00084 "consecutive problems are infeasibles by the NLP sub-solver.");
00085 roptions->setOptionExtraInfo("max_consecutive_infeasible",8);
00086
00087 roptions->SetRegisteringCategory("Nlp solution robustness", RegisteredOptions::BonminCategory);
00088 roptions->AddLowerBoundedIntegerOption
00089 ("max_consecutive_failures",
00090 "(temporarily removed) Number $n$ of consecutive unsolved problems before aborting a branch of the tree.",
00091 0,10,
00092 "When $n > 0$, continue exploring a branch of the tree until $n$ "
00093 "consecutive problems in the branch are unsolved (we call unsolved a problem for which Ipopt can not "
00094 "guarantee optimality within the specified tolerances).");
00095 roptions->setOptionExtraInfo("max_consecutive_failures",8);
00096
00097 }
00098
00099
00100
00101
00102
00103 BonCbcPartialNodeInfo::BonCbcPartialNodeInfo ()
00104 : CbcPartialNodeInfo(),
00105 sequenceOfInfeasiblesSize_(0),
00106 sequenceOfUnsolvedSize_(0)
00107 {}
00108
00109 BonCbcPartialNodeInfo::BonCbcPartialNodeInfo (CbcModel * model,CbcNodeInfo *parent, CbcNode *owner,
00110 int numberChangedBounds,
00111 const int *variables,
00112 const double *boundChanges,
00113 const CoinWarmStartDiff *basisDiff)
00114 : CbcPartialNodeInfo(parent,owner,numberChangedBounds,variables,
00115 boundChanges,basisDiff),
00116 sequenceOfInfeasiblesSize_(0),
00117 sequenceOfUnsolvedSize_(0)
00118 {
00119 BonCbcPartialNodeInfo * nlpParent = dynamic_cast<BonCbcPartialNodeInfo *> (parent);
00120 int numberInfeasible = 0;
00121 int numberUnsolved = 0;
00122 if (nlpParent)
00123 {
00124 numberInfeasible = nlpParent->getSequenceOfInfeasiblesSize();
00125 numberUnsolved = nlpParent->getSequenceOfUnsolvedSize();
00126
00127
00128
00129
00130 }
00131 else {
00132 BonCbcFullNodeInfo * nlpRoot = dynamic_cast<BonCbcFullNodeInfo *> (parent);
00133 if (nlpRoot) {
00134 numberInfeasible = nlpRoot->getSequenceOfInfeasiblesSize();
00135 numberUnsolved = nlpRoot->getSequenceOfUnsolvedSize();
00136 }
00137 }
00138 if (model->solver()->isAbandoned() ||
00139 model->solver()->isIterationLimitReached())
00140 sequenceOfUnsolvedSize_ = numberUnsolved + 1;
00141
00142 if (model->solver()->isProvenPrimalInfeasible())
00143 sequenceOfInfeasiblesSize_ = numberInfeasible + 1;
00144 }
00145
00146 BonCbcPartialNodeInfo::BonCbcPartialNodeInfo (const BonCbcPartialNodeInfo & rhs)
00147
00148 : CbcPartialNodeInfo(rhs),
00149 sequenceOfInfeasiblesSize_(rhs.sequenceOfInfeasiblesSize_),
00150 sequenceOfUnsolvedSize_(rhs.sequenceOfUnsolvedSize_)
00151
00152 {}
00153
00154 CbcNodeInfo *
00155 BonCbcPartialNodeInfo::clone() const
00156 {
00157 return (new BonCbcPartialNodeInfo(*this));
00158 }
00159
00160 void
00161 BonCbcPartialNodeInfo::allBranchesGone()
00162 {
00163 IpoptWarmStartDiff * ipws = dynamic_cast<IpoptWarmStartDiff *>(basisDiff_);
00164 if (ipws)
00165 ipws->flushPoint();
00166 }
00167
00168 BonCbcPartialNodeInfo::~BonCbcPartialNodeInfo ()
00169 {}
00170 }