CouenneProblem.hpp

Go to the documentation of this file.
00001 /* $Id: CouenneProblem.hpp 795 2012-01-26 03:19:52Z pbelotti $
00002  *
00003  * Name:    CouenneProblem.hpp
00004  * Author:  Pietro Belotti, Lehigh University
00005  *          Andreas Waechter, IBM
00006  * Purpose: define the class CouenneProblem
00007  *
00008  * (C) Carnegie-Mellon University, 2006-10.
00009  * This file is licensed under the Eclipse Public License (EPL)
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     //   bool is_less = 0;
00089     //   if(a.get_code() < b.get_code() )
00090     //  is_less = 1;
00091     //   else {
00092     //  if(a.get_code() == b.get_code() ) {
00093     //    if(a.get_coeff() < b.get_coeff() )
00094     //      is_less = 1;
00095     //    else{
00096     //      if(a.get_coeff() ==  b.get_coeff() ) {
00097     //        if(a.get_lb() < b.get_lb())
00098     //          is_less = 1;
00099     //        else{
00100     //          if(a.get_lb() == b.get_lb()) {
00101     //            if(a.get_ub() < b.get_ub())
00102     //              is_less = 1;
00103     //            else{
00104     //              if(a.get_ub() == b.get_ub()) {
00105                     
00106     //                if(a.get_index() < b.get_index())
00107     //                  is_less = 1;
00108     //              }
00109     //            }
00110     //          }
00111     //        }
00112     //      }
00113     //    }
00114     //  }
00115     //   }
00116     // return is_less;
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   //  class JnlstPtr;
00145   //  class ConstJnlstPtr;
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 // default tolerance for checking feasibility (and integrality) of NLP solutions
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   // min depth for strong branching output
00177   int minDepthPrint_;
00178 
00179   // min number of nodes for strong branching output
00180   int minNodePrint_;
00181 
00182   // indicate if strong branching output should be printed
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   // to speedup sorting operations in strong branching
00305   int lastPrioSort_;
00306 
00307   // to record best solution found
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   // Symmetry Info
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   // bool node_sort (  Node  a, Node  b);
00379   // bool index_sort (  Node  a, Node  b);
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   // get elements from vectors
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   // Get and set current variable and bounds
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   // get and set current variable and bounds
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   // get optimal solution and objective value
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   // Add (non linear) "=", ">=", "<=", and range constraints
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   // bound tightening parameters
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   //void initAuxs (const CouNumber *, const CouNumber *, const CouNumber *);
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 26 Jan 2012 for Couenne by  doxygen 1.6.1