00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <cassert>
00012 #include <cmath>
00013 #include <cfloat>
00014
00015 #include "CoinPragma.hpp"
00016 #include "OsiSolverInterface.hpp"
00017 #include "CbcModel.hpp"
00018 #include "BonCbcNlpStrategy.hpp"
00019 #include "BonCbcNode.hpp"
00020
00021 #include "BonOsiTMINLPInterface.hpp"
00022 namespace Bonmin
00023 {
00024
00025 CbcNlpStrategy::CbcNlpStrategy(int maxFailures,
00026 int maxInfeasibles,
00027 int pretendFailIsInfeasible)
00028 :
00029 hasFailed_(false),
00030 maxFailure_(maxFailures),
00031 maxInfeasible_(maxInfeasibles),
00032 pretendFailIsInfeasible_(pretendFailIsInfeasible)
00033 {
00034 setPreProcessState(0);
00035 }
00036
00037
00038
00039 CbcNlpStrategy::~CbcNlpStrategy ()
00040 {}
00041
00042
00043 CbcStrategy *
00044 CbcNlpStrategy::clone() const
00045 {
00046 return new CbcNlpStrategy(*this);
00047 }
00048
00049
00050 CbcNlpStrategy::CbcNlpStrategy(const CbcNlpStrategy & rhs)
00051 :
00052 hasFailed_(false),
00053 maxFailure_(rhs.maxFailure_),
00054 maxInfeasible_(rhs.maxInfeasible_),
00055 pretendFailIsInfeasible_(rhs.pretendFailIsInfeasible_)
00056 {}
00057
00058 CbcNodeInfo *
00059 CbcNlpStrategy::fullNodeInfo(CbcModel * model,int numberRowsAtContinuous) const
00060 {
00061 return new CbcFullNodeInfo(model,numberRowsAtContinuous);
00062 }
00063
00064 CbcNodeInfo *
00065 CbcNlpStrategy::partialNodeInfo(CbcModel * model, CbcNodeInfo * parent, CbcNode * owner,
00066 int numberChangedBounds,const int * variables,
00067 const double * boundChanges,
00068 const CoinWarmStartDiff *basisDiff) const
00069 {
00070 return new BonCbcPartialNodeInfo(model,parent, owner, numberChangedBounds, variables,
00071 boundChanges,basisDiff);
00072 }
00073
00074
00075
00076
00077
00078
00079 int
00080 CbcNlpStrategy::status(CbcModel * model, CbcNodeInfo * parent,int whereFrom)
00081 {
00082
00083 OsiSolverInterface * solver = model->solver();
00084 int feasible = 1;
00085 bool solved = true;
00086 int returnStatus = -1;
00087 BonCbcPartialNodeInfo * bmNodeInfo = dynamic_cast<BonCbcPartialNodeInfo *>(parent);
00088 if (!bmNodeInfo) return -1;
00089
00090 int seqOfInfeasiblesSize = bmNodeInfo->getSequenceOfInfeasiblesSize();
00091 int seqOfUnsolvedSize = bmNodeInfo->getSequenceOfUnsolvedSize();
00092
00093
00094 if (solver->isAbandoned()) {
00095 solved = false;
00096 seqOfUnsolvedSize++;
00097 ;
00098 }
00099 else if (solver->isProvenPrimalInfeasible()) {
00100 feasible = 0;
00101 seqOfInfeasiblesSize++;
00102 }
00103
00104 if (((seqOfUnsolvedSize==0) || (maxFailure_ == 0)) &&
00105 ((maxInfeasible_== 0) || (seqOfInfeasiblesSize==0)))
00106
00107 if (feasible && seqOfInfeasiblesSize > 1) {
00108 (*model->messageHandler())<<"Feasible node while father was infeasible."
00109 <<CoinMessageEol;
00110 }
00111
00112 if (solved && seqOfUnsolvedSize > 1) {
00113 (*model->messageHandler())<<"Solved node while father was unsolved."
00114 <<CoinMessageEol;
00115 }
00116
00117 if (seqOfInfeasiblesSize < maxInfeasible_ &&
00118 solved && !feasible) {
00119 (*model->messageHandler())<<"Branching on infeasible node, sequence of infeasible size "
00120 <<seqOfInfeasiblesSize<<CoinMessageEol;
00121
00122 OsiTMINLPInterface * ipopt = dynamic_cast<OsiTMINLPInterface *>(solver);
00123 ipopt->forceBranchable();
00124
00125 returnStatus = 0;
00126
00127 }
00128
00129 if (!solved && parent != NULL &&
00130 seqOfUnsolvedSize <= maxFailure_) {
00131 (*model->messageHandler())<<"Branching on unsolved node, sequence of unsolved size "<<seqOfUnsolvedSize<<CoinMessageEol;
00132
00133 OsiTMINLPInterface * osiMinlp = dynamic_cast<OsiTMINLPInterface *>(solver);
00134 osiMinlp->forceBranchable();
00135 returnStatus = 0;
00136 }
00137
00138 if (solver->isAbandoned() && parent != NULL &&
00139 seqOfUnsolvedSize > maxFailure_) {
00140 hasFailed_ = true;
00141 OsiTMINLPInterface * osiMinlp =
00142 dynamic_cast<OsiTMINLPInterface *>(solver);
00143 if (pretendFailIsInfeasible_) {
00144
00145 osiMinlp->forceInfeasible();
00146 returnStatus = 2;
00147 }
00148 else {
00149 std::string probName;
00150 osiMinlp->getStrParam(OsiProbName,probName);
00151 throw osiMinlp->newUnsolvedError(0, osiMinlp->problem(), probName);
00152 }
00153 }
00154 return returnStatus;
00155 }
00156
00157 void
00158 CbcNlpStrategy::setupCutGenerators(CbcModel &model)
00159 {}
00160
00161 void
00162 CbcNlpStrategy::setupHeuristics(CbcModel &model)
00163 {}
00164
00165 void
00166 CbcNlpStrategy::setupPrinting(CbcModel &model, int toto)
00167 {}
00168
00169 void
00170 CbcNlpStrategy::setupOther(CbcModel &model)
00171 {}
00172 }