00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef COUENNE_PROBLEM_HPP
00013 #define COUENNE_PROBLEM_HPP
00014
00015 #define FM_TRACE_OPTSOL
00016 #define FM_CHECKNLP2
00017
00018 #include <vector>
00019 #include <map>
00020
00021 #include "CouenneConfig.h"
00022
00023 #include "CouenneTypes.hpp"
00024 #include "CouenneExpression.hpp"
00025
00026 #include "CouenneJournalist.hpp"
00027 #include "CouenneDomain.hpp"
00028
00029 namespace Ipopt {
00030 template <class T> class SmartPtr;
00031 class OptionsList;
00032 class Journalist;
00033 }
00034
00035 namespace Bonmin {
00036 class RegisteredOptions;
00037 class BabInfo;
00038 class OsiTMINLPInterface;
00039 class BabSetupBase;
00040 }
00041
00042 struct ASL;
00043 struct expr;
00044
00045 class CglTreeInfo;
00046 class CbcModel;
00047 class OsiObject;
00048 class CoinWarmStart;
00049
00050 class Nauty;
00051
00052 class Node{
00053 int index;
00054 double coeff;
00055 double lb;
00056 double ub;
00057 int color;
00058 int code;
00059 int sign;
00060 public:
00061 void node(int, double, double, double, int, int);
00062 inline void color_vertex (register int k) {color = k;}
00063 inline int get_index () const {return index;}
00064 inline double get_coeff () const {return coeff;}
00065 inline double get_lb () const {return lb;}
00066 inline double get_ub () const {return ub;}
00067 inline int get_color () const {return color;}
00068 inline int get_code () const {return code;}
00069 inline int get_sign () const {return sign;}
00070 inline void bounds(register double a, register double b){ lb = a; ub = b;}
00071 };
00072
00073 #define COUENNE_EPS_SYMM 1e-8
00074
00075 struct myclass0 {
00076 inline bool operator() (register const Node &a, register const Node &b) {
00077
00078 return (( a.get_code () < b.get_code ()) ||
00079 (( a.get_code () == b.get_code () &&
00080 (( a.get_coeff () < b.get_coeff () - COUENNE_EPS_SYMM) ||
00081 ((fabs (a.get_coeff () - b.get_coeff ()) < COUENNE_EPS_SYMM) &&
00082 (( a.get_lb () < b.get_lb () - COUENNE_EPS_SYMM) ||
00083 ((fabs (a.get_lb () - b.get_lb ()) < COUENNE_EPS_SYMM) &&
00084 (( a.get_ub () < b.get_ub () - COUENNE_EPS_SYMM) ||
00085 ((fabs (a.get_ub () - b.get_ub ()) < COUENNE_EPS_SYMM) &&
00086 (( a.get_index () < b.get_index ()))))))))))) ? 1 : 0;
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 }
00119 } ;
00120
00121
00122 struct myclass {
00123 inline bool operator() (register const Node &a, register const Node &b) {
00124 return (a.get_index() < b.get_index() );
00125 }
00126 };
00127
00128
00129 namespace Couenne {
00130
00131 enum TrilinDecompType {rAI, treeDecomp, bi_tri, tri_bi};
00132
00133 class exprVar;
00134 class exprAux;
00135 class DepGraph;
00136 class CouenneObject;
00137 class CouenneCutGenerator;
00138 class quadElem;
00139 class LinMap;
00140 class QuadMap;
00141 class CouenneConstraint;
00142 class CouenneObjective;
00143 class GlobalCutOff;
00144
00145
00146 class CouenneRecordBestSol;
00147
00148 typedef Ipopt::SmartPtr<Ipopt::Journalist> JnlstPtr;
00149 typedef Ipopt::SmartPtr<const Ipopt::Journalist> ConstJnlstPtr;
00150
00151 struct compExpr;
00152
00153
00154 const CouNumber feas_tolerance_default = 1e-5;
00155
00164 class CouenneProblem {
00165
00166 friend class exprMul;
00167
00169 enum fixType {UNFIXED, FIXED, CONTINUOUS};
00170
00171 public:
00172
00174 enum multiSep {MulSepNone, MulSepSimple, MulSepTight};
00175
00176
00177 int minDepthPrint_;
00178
00179
00180 int minNodePrint_;
00181
00182
00183 bool doPrint_;
00184
00185 protected:
00186
00188 std::string problemName_;
00189
00190 std::vector <exprVar *> variables_;
00191 std::vector <CouenneObjective *> objectives_;
00192 std::vector <CouenneConstraint *> constraints_;
00193
00195 std::vector <expression *> commonexprs_;
00196
00197 mutable Domain domain_;
00198
00201 std::set <exprAux *, compExpr> *auxSet_;
00202
00204 mutable int curnvars_;
00205
00207 int nIntVars_;
00208
00210 mutable CouNumber *optimum_;
00211
00213 CouNumber bestObj_;
00214
00216 int *quadIndex_;
00217
00219 bool *commuted_;
00220
00223 int *numbering_;
00224
00226 int ndefined_;
00227
00232 DepGraph *graph_;
00233
00235 int nOrigVars_;
00236
00239 int nOrigCons_;
00240
00242 int nOrigIntVars_;
00243
00245 mutable GlobalCutOff* pcutoff_;
00246
00248 mutable bool created_pcutoff_;
00249
00250 bool doFBBT_;
00251 bool doRCBT_;
00252 bool doOBBT_;
00253 bool doABT_;
00254
00255 int logObbtLev_;
00256 int logAbtLev_;
00257
00259 JnlstPtr jnlst_;
00260
00262 CouNumber opt_window_;
00263
00265 bool useQuadratic_;
00266
00268 CouNumber feas_tolerance_;
00269
00273 std::vector <std::set <int> > dependence_;
00274
00278 std::vector <CouenneObject *> objects_;
00279
00282 mutable int *integerRank_;
00283
00285 mutable std::vector <int> numberInRank_;
00286
00288 double maxCpuTime_;
00289
00291 Bonmin::BabSetupBase *bonBase_;
00292
00294 ASL *asl_;
00295
00299 int *unusedOriginalsIndices_;
00300
00302 int nUnusedOriginals_;
00303
00304
00305 int lastPrioSort_;
00306
00307
00308 struct Couenne::CouenneRecordBestSol *recBSol;
00309
00311 enum multiSep multilinSep_;
00312
00314 int max_fbbt_iter_;
00315
00318 mutable bool fbbtReachedIterLimit_;
00319
00321 bool orbitalBranching_;
00322
00327 bool checkAuxBounds_;
00328
00330 enum TrilinDecompType trilinDecompType_;
00331
00333 double constObjVal_;
00334
00335 public:
00336
00337 CouenneProblem (ASL * = NULL,
00338 Bonmin::BabSetupBase *base = NULL,
00339 JnlstPtr jnlst = NULL);
00340 CouenneProblem (const CouenneProblem &);
00341 ~CouenneProblem ();
00342
00344 void initOptions (Ipopt::SmartPtr <Ipopt::OptionsList> options);
00345
00347 CouenneProblem *clone () const
00348 {return new CouenneProblem (*this);}
00349
00350 int nObjs () const {return (int) objectives_. size ();}
00351 int nCons () const {return (int) constraints_. size ();}
00352 int nOrigCons () const {return nOrigCons_;}
00353
00354 inline int nOrigVars () const {return nOrigVars_;}
00355 inline int nDefVars () const {return ndefined_;}
00356 inline int nOrigIntVars () const {return nOrigIntVars_;}
00357 inline int nIntVars () const {return nIntVars_;}
00358 inline int nVars () const {return (int) variables_. size ();}
00359
00360 void setNDefVars (int ndefined__) {ndefined_ = ndefined__;}
00361
00362
00363
00364 std::vector<int> *Find_Orbit(int) const;
00365 mutable std::vector<Node> node_info;
00366 mutable Nauty *nauty_info;
00367
00368 myclass0 node_sort;
00369 myclass index_sort;
00370
00371 void sym_setup();
00372 void Compute_Symmetry() const;
00373 void Print_Orbits() const;
00374 void ChangeBounds (const double * , const double *, int ) const;
00375 inline bool compare (register Node &a, register Node &b) const;
00376 Nauty *getNtyInfo () {return nauty_info;}
00377
00378
00379
00380
00382 void setupSymmetry ();
00383
00385 inline int evalOrder (int i) const
00386 {return numbering_ [i];}
00387
00389 inline int *evalVector ()
00390 {return numbering_;}
00391
00392
00393 inline CouenneConstraint *Con (int i) const {return constraints_ [i];}
00394 inline CouenneObjective *Obj (int i) const {return objectives_ [i];}
00395
00397 inline exprVar *Var (int i) const
00398 {return variables_ [i];}
00399
00401 inline std::vector <exprVar *> &Variables ()
00402 {return variables_;}
00403
00405 inline std::set <exprAux *, compExpr> *& AuxSet ()
00406 {return auxSet_;}
00407
00409 inline DepGraph *getDepGraph ()
00410 {return graph_;}
00411
00413 inline Domain *domain () const
00414 {return &domain_;}
00415
00416 inline std::vector <expression *>& commonExprs() { return commonexprs_; }
00417
00418
00419 inline CouNumber &X (int i) const {return domain_.x (i);}
00420 inline CouNumber &Lb (int i) const {return domain_.lb (i);}
00421 inline CouNumber &Ub (int i) const {return domain_.ub (i);}
00422
00423
00424 inline CouNumber *X () const {return domain_.x ();}
00425 inline CouNumber *Lb () const {return domain_.lb ();}
00426 inline CouNumber *Ub () const {return domain_.ub ();}
00427
00428
00429 CouNumber *&bestSol () const {return optimum_;}
00430 CouNumber bestObj () const {return bestObj_;}
00431
00433 bool *&Commuted ()
00434 {return commuted_;}
00435
00437 void addObjective (expression *, const std::string & = "min");
00438
00439
00440 void addEQConstraint (expression *, expression * = NULL);
00441 void addGEConstraint (expression *, expression * = NULL);
00442 void addLEConstraint (expression *, expression * = NULL);
00443 void addRNGConstraint (expression *, expression * = NULL,
00444 expression * = NULL);
00445
00447 void setObjective (int indObj = 0, expression * = NULL, const std::string & = "min");
00448
00453 expression *addVariable (bool isint = false, Domain *d = NULL);
00454
00457 exprAux *addAuxiliary (expression *);
00458
00460 void reformulate (CouenneCutGenerator * = NULL);
00461
00465 bool standardize ();
00466
00469 void print (std::ostream & = std::cout);
00470
00471 #ifdef COIN_HAS_ASL
00473 int readnl (const struct ASL *);
00474
00476 expression *nl2e (struct expr *, const ASL *asl);
00477 #endif
00478
00479
00480 bool doFBBT () const {return doFBBT_;}
00481 bool doRCBT () const {return doRCBT_;}
00482 bool doOBBT () const {return doOBBT_;}
00483 bool doABT () const {return doABT_;}
00484
00485 int logObbtLev () const {return logObbtLev_;}
00486 int logAbtLev () const {return logAbtLev_;}
00487
00500 void writeAMPL (const std::string &fname, bool aux);
00501
00505 void writeGAMS (const std::string &fname);
00506
00509
00510 void initAuxs () const;
00511
00513 void getAuxs (CouNumber *) const;
00514
00516 bool boundTightening (t_chg_bounds *,
00517 Bonmin::BabInfo * = NULL) const;
00518
00520 bool btCore (t_chg_bounds *chg_bds) const;
00521
00523 int obbt (const CouenneCutGenerator *cg,
00524 const OsiSolverInterface &csi,
00525 OsiCuts &cs,
00526 const CglTreeInfo &info,
00527 Bonmin::BabInfo * babInfo,
00528 t_chg_bounds *chg_bds);
00529
00533 bool aggressiveBT (Bonmin::OsiTMINLPInterface *nlp,
00534 t_chg_bounds *,
00535 const CglTreeInfo &info,
00536 Bonmin::BabInfo * = NULL) const;
00537
00540 int redCostBT (const OsiSolverInterface *psi,
00541 t_chg_bounds *chg_bds) const;
00542
00545 int tightenBounds (t_chg_bounds *) const;
00546
00548 int impliedBounds (t_chg_bounds *) const;
00549
00551 void fillQuadIndices ();
00552
00554 void fillObjCoeff (double *&);
00555
00558 void auxiliarize (exprVar *, exprVar * = NULL);
00559
00561 void setCutOff (CouNumber cutoff, const CouNumber *sol = NULL) const;
00562
00564 void resetCutOff (CouNumber value = COUENNE_INFINITY) const;
00565
00567 CouNumber getCutOff () const;
00568
00570 CouNumber *getCutOffSol () const;
00571
00573 void installCutOff () const;
00574
00576 ConstJnlstPtr Jnlst () const;
00577
00579 bool checkNLP (const double *solution, double &obj, bool recompute = false) const;
00580
00583 int getIntegerCandidate (const double *xFrac, double *xInt, double *lb, double *ub) const;
00584
00586 bool readOptimum (std::string *fname = NULL);
00587
00589 static void registerOptions (Ipopt::SmartPtr <Bonmin::RegisteredOptions> roptions);
00590
00592 exprAux *linStandardize (bool addAux,
00593 CouNumber c0,
00594 LinMap &lmap,
00595 QuadMap &qmap);
00596
00599 int splitAux (CouNumber, expression *, expression *&, bool *, enum expression::auxSign &);
00600
00602 void indcoe2vector (int *indexL,
00603 CouNumber *coeff,
00604 std::vector <std::pair <exprVar *, CouNumber> > &lcoeff);
00605
00607 void indcoe2vector (int *indexI,
00608 int *indexJ,
00609 CouNumber *coeff,
00610 std::vector <quadElem> &qcoeff);
00611
00622 void decomposeTerm (expression *term,
00623 CouNumber initCoe,
00624 CouNumber &c0,
00625 LinMap &lmap,
00626 QuadMap &qmap);
00627
00629 const std::string &problemName () const
00630 {return problemName_;}
00631
00632 void setProblemName(std::string& problemName__)
00633 { problemName_ = problemName__; }
00634
00636 const std::vector <std::set <int> > &Dependence () const
00637 {return dependence_;}
00638
00640 const std::vector <CouenneObject *> &Objects () const
00641 {return objects_;}
00642
00644 int findSOS (CbcModel *CbcModelPtr,
00645 OsiSolverInterface *solver,
00646 OsiObject ** objects);
00647
00649 inline void setMaxCpuTime (double time)
00650 {maxCpuTime_ = time;}
00651
00653 inline double getMaxCpuTime () const
00654 {return maxCpuTime_;}
00655
00657 void setBase (Bonmin::BabSetupBase *base);
00658
00663 void createUnusedOriginals ();
00664
00668 void restoreUnusedOriginals (CouNumber * = NULL) const;
00669
00671 int *unusedOriginalsIndices ()
00672 {return unusedOriginalsIndices_;}
00673
00675 int nUnusedOriginals ()
00676 {return nUnusedOriginals_;}
00677
00679 enum multiSep MultilinSep () const
00680 {return multilinSep_;}
00681
00683 bool fbbtReachedIterLimit () const
00684 {return fbbtReachedIterLimit_;}
00685
00687 bool orbitalBranching () const
00688 {return orbitalBranching_;}
00689
00693 void setCheckAuxBounds (bool value)
00694 {checkAuxBounds_ = value;}
00695
00698 bool checkAuxBounds () const
00699 {return checkAuxBounds_;}
00700
00702 enum TrilinDecompType getTrilinDecompType ()
00703 {return trilinDecompType_;}
00704
00706 Bonmin::BabSetupBase *bonBase () const {return bonBase_;}
00707
00709 inline double constObjVal () const {return constObjVal_;}
00710
00711 protected:
00712
00718 int fake_tighten (char direction,
00719 int index,
00720 const double *X,
00721 CouNumber *olb,
00722 CouNumber *oub,
00723 t_chg_bounds *chg_bds,
00724 t_chg_bounds *f_chg) const;
00725
00727 int obbtInner (OsiSolverInterface *,
00728 OsiCuts &,
00729 t_chg_bounds *,
00730 Bonmin::BabInfo *) const;
00731
00732 int obbt_iter (OsiSolverInterface *csi,
00733 t_chg_bounds *chg_bds,
00734 const CoinWarmStart *warmstart,
00735 Bonmin::BabInfo *babInfo,
00736 double *objcoe,
00737 int sense,
00738 int index) const;
00739
00740 int call_iter (OsiSolverInterface *csi,
00741 t_chg_bounds *chg_bds,
00742 const CoinWarmStart *warmstart,
00743 Bonmin::BabInfo *babInfo,
00744 double *objcoe,
00745 enum nodeType type,
00746 int sense) const;
00747
00751 void analyzeSparsity (CouNumber,
00752 LinMap &,
00753 QuadMap &);
00754
00757 void flattenMul (expression *mul,
00758 CouNumber &coe,
00759 std::map <int, CouNumber> &indices);
00760
00762 void realign ();
00763
00765 void fillDependence (Bonmin::BabSetupBase *base, CouenneCutGenerator * = NULL);
00766
00768 void fillIntegerRank () const;
00769
00771 int testIntFix (int index,
00772 CouNumber xFrac,
00773 enum fixType *fixed,
00774 CouNumber *xInt,
00775 CouNumber *dualL, CouNumber *dualR,
00776 CouNumber *olb, CouNumber *oub,
00777 bool patient) const;
00778
00779 public:
00780
00782 inline int getLastPrioSort() const
00783 {return lastPrioSort_;};
00784
00786 void setLastPrioSort (int givenLastPS);
00787
00789 inline CouenneRecordBestSol *getRecordBestSol() const
00790 {return recBSol;};
00791
00793 double getFeasTol() {return feas_tolerance_;};
00794
00796 double checkObj(const CouNumber *sol, const double &precision) const;
00797
00801 bool checkInt(const CouNumber *sol,
00802 const int from, const int upto,
00803 const std::vector<int> listInt,
00804 const bool origVarOnly,
00805 const bool stopAtFirstViol,
00806 const double precision, double &maxViol) const;
00807
00809 bool checkBounds(const CouNumber *sol,
00810 const bool stopAtFirstViol,
00811 const double precision, double &maxViol) const;
00812
00814 bool checkAux(const CouNumber *sol,
00815 const bool stopAtFirstViol,
00816 const double precision, double &maxViol) const;
00817
00819 bool checkCons(const CouNumber *sol,
00820 const bool stopAtFirstViol,
00821 const double precision, double &maxViol) const;
00822
00835
00839
00844
00847 bool checkNLP2(const double *solution,
00848 const double obj, const bool careAboutObj,
00849 const bool stopAtFirstViol,
00850 const bool checkAll,
00851 const double precision) const;
00852 };
00853
00854 }
00855
00856 #endif