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