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