00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <vector>
00012
00013 #include "CoinHelperFunctions.hpp"
00014 #include "CoinTime.hpp"
00015
00016 #include "BonBabSetupBase.hpp"
00017
00018 #include "CouenneTypes.hpp"
00019
00020 #include "CouenneExpression.hpp"
00021 #include "CouenneExprConst.hpp"
00022 #include "CouenneExprQuad.hpp"
00023 #include "CouenneExprClone.hpp"
00024 #include "CouenneExprIVar.hpp"
00025 #include "CouenneExprAux.hpp"
00026 #include "CouenneExprOpp.hpp"
00027
00028 #include "CouenneProblem.hpp"
00029 #include "CouenneProblemElem.hpp"
00030 #include "CouenneGlobalCutOff.hpp"
00031 #include "CouenneDepGraph.hpp"
00032 #include "CouenneLQelems.hpp"
00033
00034 #include "CouenneObject.hpp"
00035
00036 #include "CouenneRecordBestSol.hpp"
00037 #include "CouenneBTPerfIndicator.hpp"
00038 #include "CouenneSdpCuts.hpp"
00039
00040 #ifdef COIN_HAS_NTY
00041 #include "Nauty.h"
00042 #endif
00043
00044 using namespace Couenne;
00045
00046 #define MAX_FBBT_ITER 3
00047
00049 CouenneProblem::CouenneProblem (struct ASL *asl,
00050 Bonmin::BabSetupBase *base,
00051 JnlstPtr jnlst):
00052 problemName_ (""),
00053 auxSet_ (NULL),
00054 curnvars_ (-1),
00055 nIntVars_ (0),
00056 optimum_ (NULL),
00057 bestObj_ (COIN_DBL_MAX),
00058 commuted_ (NULL),
00059 numbering_ (NULL),
00060 ndefined_ (0),
00061 graph_ (NULL),
00062 nOrigVars_ (0),
00063 nOrigIntVars_ (0),
00064 pcutoff_ (new GlobalCutOff (COIN_DBL_MAX)),
00065 created_pcutoff_ (true),
00066 doFBBT_ (true),
00067 doRCBT_ (true),
00068 doOBBT_ (true),
00069 doABT_ (true),
00070 logObbtLev_(0),
00071 logAbtLev_ (0),
00072 jnlst_ (jnlst),
00073 opt_window_ (COIN_DBL_MAX),
00074 useQuadratic_ (false),
00075 feas_tolerance_ (feas_tolerance_default),
00076 integerRank_ (NULL),
00077 maxCpuTime_ (COIN_DBL_MAX),
00078 bonBase_ (base),
00079 #ifdef COIN_HAS_ASL
00080 asl_ (asl),
00081 #endif
00082 unusedOriginalsIndices_ (NULL),
00083 nUnusedOriginals_ (-1),
00084 multilinSep_ (CouenneProblem::MulSepNone),
00085 max_fbbt_iter_ (MAX_FBBT_ITER),
00086 orbitalBranching_ (false),
00087 constObjVal_ (0.),
00088 perfIndicator_ (new CouenneBTPerfIndicator (this, "FBBT")),
00089
00090 nauty_info (NULL),
00091 sdpCutGen_ (NULL) {
00092
00093 double now = CoinCpuTime ();
00094
00095 if (asl) {
00096 #if COIN_HAS_ASL
00097
00098 readnl (asl);
00099 #else
00100 jnlst_ -> Printf (Ipopt::J_ERROR, J_PROBLEM, "Couenne was compiled without the ASL library. Cannot process ASL structure.\n");
00101 throw -1;
00102 #endif
00103
00104 if ((now = (CoinCpuTime () - now)) > 10.)
00105 jnlst_ -> Printf (Ipopt::J_WARNING, J_PROBLEM,
00106 "Couenne: reading time %.3fs\n", now);
00107 }
00108
00109
00110 auxSet_ = new std::set <exprAux *, compExpr>;
00111
00112 if (base)
00113 initOptions (base -> options());
00114
00115 recBSol = new CouenneRecordBestSol();
00116 lastPrioSort_ = 1000000;
00117
00118 minDepthPrint_ = -1;
00119 minNodePrint_ = -1;
00120 doPrint_ = false;
00121 }
00122
00123
00125
00126 CouenneProblem::CouenneProblem (const CouenneProblem &p):
00127 problemName_ (p.problemName_),
00128 domain_ (p.domain_),
00129 curnvars_ (-1),
00130 nIntVars_ (p.nIntVars_),
00131 optimum_ (NULL),
00132 bestObj_ (p.bestObj_),
00133 commuted_ (NULL),
00134 numbering_ (NULL),
00135 ndefined_ (p.ndefined_),
00136 graph_ (NULL),
00137 nOrigVars_ (p.nOrigVars_),
00138 nOrigCons_ (p.nOrigCons_),
00139 nOrigIntVars_ (p.nOrigIntVars_),
00140 pcutoff_ (p.pcutoff_),
00141 created_pcutoff_ (false),
00142 doFBBT_ (p. doFBBT_),
00143 doRCBT_ (p. doRCBT_),
00144 doOBBT_ (p. doOBBT_),
00145 doABT_ (p. doABT_),
00146 logObbtLev_ (p. logObbtLev_),
00147 logAbtLev_ (p. logAbtLev_),
00148 jnlst_ (p.jnlst_),
00149 opt_window_ (p.opt_window_),
00150 useQuadratic_ (p.useQuadratic_),
00151 feas_tolerance_ (p.feas_tolerance_),
00152 dependence_ (p.dependence_),
00153 objects_ (p.objects_),
00154 integerRank_ (NULL),
00155 numberInRank_ (p.numberInRank_),
00156 maxCpuTime_ (p.maxCpuTime_),
00157 bonBase_ (p.bonBase_),
00158 #ifdef COIN_HAS_ASL
00159 asl_ (p.asl_),
00160 #endif
00161 unusedOriginalsIndices_ (NULL),
00162 nUnusedOriginals_ (p.nUnusedOriginals_),
00163 multilinSep_ (p.multilinSep_),
00164 max_fbbt_iter_ (p.max_fbbt_iter_),
00165 orbitalBranching_ (p.orbitalBranching_),
00166 constObjVal_ (p.constObjVal_),
00167 perfIndicator_ (new CouenneBTPerfIndicator (*(p.perfIndicator_))),
00168 nauty_info (p.nauty_info) {
00169
00170 sdpCutGen_ = new CouenneSdpCuts (*(p.sdpCutGen_));
00171
00172 for (int i=0; i < p.nVars (); i++)
00173 variables_ . push_back (NULL);
00174
00175 for (int i=0; i < p.nVars (); i++) {
00176 int ind = p.numbering_ [i];
00177 variables_ [ind] = p.Var (ind) -> clone (&domain_);
00178 }
00179
00180 for (std::vector <CouenneObject *>::iterator i = objects_.begin ();
00181 i != objects_.end (); ++i)
00182 (*i) = (*i) -> clone ();
00183
00184 if (p.numbering_)
00185 numbering_ = CoinCopyOfArray (p.numbering_, nVars ());
00186
00187
00188 for (int i=0; i < p.nObjs (); i++) objectives_ . push_back (p.Obj (i) -> clone (&domain_));
00189 for (int i=0; i < p.nCons (); i++) constraints_ . push_back (p.Con (i) -> clone (&domain_));
00190
00191 if (p.optimum_)
00192 optimum_ = CoinCopyOfArray (p.optimum_, nVars ());
00193
00194
00195 realign ();
00196
00197
00198 if (p.integerRank_) {
00199 integerRank_ = new int [nVars ()];
00200 CoinCopyN (p.integerRank_, nVars (), integerRank_);
00201 }
00202
00203
00204 if (nUnusedOriginals_ > 0) {
00205 unusedOriginalsIndices_ = (int *) malloc (nUnusedOriginals_ * sizeof (int));
00206 CoinCopyN (p.unusedOriginalsIndices_, nUnusedOriginals_, unusedOriginalsIndices_);
00207 }
00208
00209 if (p.recBSol) recBSol = new CouenneRecordBestSol (*(p.recBSol));
00210 else recBSol = new CouenneRecordBestSol ();
00211
00212 lastPrioSort_ = p.lastPrioSort_;
00213
00214 minDepthPrint_ = p.minDepthPrint_;
00215 minNodePrint_ = p.minNodePrint_;
00216 doPrint_ = p.doPrint_;
00217 }
00218
00219
00221
00222 CouenneProblem::~CouenneProblem () {
00223
00224 if (sdpCutGen_)
00225 delete sdpCutGen_;
00226
00227 delete auxSet_;
00228
00229 if (perfIndicator_)
00230 delete perfIndicator_;
00231
00232
00233 if (optimum_)
00234 free (optimum_);
00235
00236
00237 for (std::vector <CouenneObjective *>::iterator i = objectives_ . begin ();
00238 i != objectives_ . end (); ++i)
00239 delete (*i);
00240
00241
00242 for (std::vector <CouenneConstraint *>::iterator i = constraints_ . begin ();
00243 i != constraints_ . end (); ++i)
00244 delete (*i);
00245
00246
00247
00248 if (numbering_) for (int i=nVars (); i--;) delete variables_ [numbering_ [i]];
00249 else for (int i=nVars (); i--;) delete variables_ [i];
00250
00251
00252 if (graph_) delete graph_;
00253 if (commuted_) delete [] commuted_;
00254 if (numbering_) delete [] numbering_;
00255
00256 if (created_pcutoff_) delete pcutoff_;
00257
00258 if (integerRank_) delete [] integerRank_;
00259
00260 if (unusedOriginalsIndices_)
00261 free (unusedOriginalsIndices_);
00262
00263 for (std::vector <CouenneObject *>::iterator i = objects_.begin ();
00264 i != objects_.end (); ++i)
00265 delete (*i);
00266
00267 #ifdef COIN_HAS_NTY
00268 if (nauty_info)
00269 delete nauty_info;
00270 #endif
00271
00272 delete recBSol;
00273 }
00274
00275
00277 void CouenneProblem::initOptions (Ipopt::SmartPtr<Ipopt::OptionsList> options) {
00278
00279 assert(IsValid(options));
00280
00281 std::string s;
00282
00283 options -> GetStringValue ("use_quadratic", s, "couenne."); useQuadratic_ = (s == "yes");
00284 options -> GetStringValue ("feasibility_bt", s, "couenne."); doFBBT_ = (s == "yes");
00285 options -> GetStringValue ("redcost_bt", s, "couenne."); doRCBT_ = (s == "yes");
00286 options -> GetStringValue ("optimality_bt", s, "couenne."); doOBBT_ = (s == "yes");
00287 options -> GetStringValue ("aggressive_fbbt", s, "couenne."); doABT_ = (s == "yes");
00288
00289 options -> GetIntegerValue ("log_num_obbt_per_level", logObbtLev_, "couenne.");
00290 options -> GetIntegerValue ("log_num_abt_per_level", logAbtLev_, "couenne.");
00291
00292 options -> GetIntegerValue ("max_fbbt_iter", max_fbbt_iter_, "couenne.");
00293
00294 options -> GetNumericValue ("feas_tolerance", feas_tolerance_, "couenne.");
00295 options -> GetNumericValue ("opt_window", opt_window_, "couenne.");
00296
00297 options -> GetStringValue ("multilinear_separation", s, "couenne.");
00298 multilinSep_ = (s == "none" ? CouenneProblem::MulSepNone :
00299 s == "simple" ? CouenneProblem::MulSepSimple :
00300 CouenneProblem::MulSepTight);
00301
00302 options -> GetStringValue ("orbital_branching", s, "couenne."); orbitalBranching_ = (s == "yes");
00303
00304 options -> GetStringValue ("quadrilinear_decomp", s, "couenne.");
00305 if (s == "rAI") trilinDecompType_ = rAI;
00306 else if (s == "tri+bi") trilinDecompType_ = tri_bi;
00307 else if (s == "bi+tri") trilinDecompType_ = bi_tri;
00308 else if (s == "hier-bi") trilinDecompType_ = treeDecomp;
00309 }