IpoptInterface.hpp

Go to the documentation of this file.
00001 // (C) Copyright International Business Machines Corporation, Carnegie Mellon University 2004
00002 // All Rights Reserved.
00003 // This code is published under the Common Public License.
00004 //
00005 // Authors :
00006 // Pierre Bonami, Carnegie Mellon University,
00007 // Carl D. Laird, Carnegie Mellon University,
00008 // Andreas Waechter, International Business Machines Corporation
00009 //
00010 // Date : 12/01/2004
00011 
00012 
00013 #ifndef IpoptInterface_H
00014 #define IpoptInterface_H
00015 
00016 #include "BonminConfig.h"
00017 
00018 #include <string>
00019 #include <iostream>
00020 
00021 #include "OsiSolverInterface.hpp"
00022 #include "CoinWarmStartBasis.hpp"
00023 
00024 #include "TMINLP.hpp"
00025 #include "TMINLP2TNLP.hpp"
00026 #include "TNLP2FPNLP.hpp"
00027 #ifdef COIN_HAS_GAMSLINKS
00028 #include "CoinMessageHandler2Journal.hpp"
00029 #endif
00030 #include "IpIpoptApplication.hpp"
00031 
00032 
00038 class IpoptInterface : public OsiSolverInterface
00039 {
00040   friend class BonminParam;
00041 
00042 public:
00043 
00044   //#############################################################################
00045 
00050 class SimpleError : public CoinError
00051   {
00052   public:
00054     SimpleError(std::string message,
00055         std::string methodName)
00056         :
00057         CoinError(message,methodName,std::string("IpoptInterface"))
00058     {}
00060     SimpleError (const char * message,
00061         const char * methodName)
00062         :
00063         CoinError(message,methodName,"IpoptInterface")
00064     {}
00065 
00066   private:
00067    SimpleError();
00068   }
00069   ;
00070 
00071   //#############################################################################
00072 
00075   class UnsolvedError
00076   {
00077   public:
00079     UnsolvedError(int errorNum_ = 10000);
00081     void printError(std::ostream & os);
00083     const std::string& errorName() const;
00084   private:
00085     int errorNum_;
00086     static std::string errorNames [17];
00087   }
00088   ;
00089 
00090 
00091   //#############################################################################
00092 
00093 
00095   enum MessagesTypes{
00096     SOLUTION_FOUND,
00097     INFEASIBLE_SOLUTION_FOUND,
00098     UNSOLVED_PROBLEM_FOUND,
00099     WARNING_RESOLVING ,
00100     WARN_SUCCESS_WS,
00101     WARN_SUCCESS_RANDOM,
00102     WARN_CONTINUING_ON_FAILURE,
00103     SUSPECT_PROBLEM,
00104     SUSPECT_PROBLEM2,
00105     IPOPT_SUMMARY ,
00106     BETTER_SOL ,
00107     LOG_HEAD,
00108     LOG_FIRST_LINE,
00109     LOG_LINE,
00110     WARN_RESOLVE_BEFORE_INITIAL_SOLVE ,
00113     WARN_NONCONVEX_OA,
00114     WARN_FREEDOM,
00115     IPOTPINTERFACE_DUMMY_END
00116   };
00117 
00118   //#############################################################################
00119 
00120 
00122 class Messages : public CoinMessages
00123   {
00124   public:
00126     Messages();
00127   };
00128 
00129 
00130   //#############################################################################
00131 
00132 
00135 
00136   IpoptInterface();
00140   IpoptInterface (Ipopt::SmartPtr<Ipopt::TMINLP> tminlp
00141 #ifdef COIN_HAS_GAMSLINKS
00142 , CoinMessageHandler* messageHandler=NULL
00143 #endif
00144  );
00146   virtual OsiSolverInterface * clone(bool CopyData=true) const;
00147 
00150   IpoptInterface (const IpoptInterface &);
00151 
00153   IpoptInterface & operator=(const IpoptInterface& rhs);
00154 
00156   virtual ~IpoptInterface ();
00157 
00158 
00160   Ipopt::SmartPtr<Ipopt::OptionsList> retrieve_options();
00161 
00163   void register_ALL_options (Ipopt::SmartPtr<Ipopt::RegisteredOptions> roptions);
00164 
00166   void set_ipopt_minlp_default(SmartPtr<OptionsList> Options);
00167 
00169   void readOptionFile(const char * fileName);
00171 
00172   void extractInterfaceParams();
00173 
00174   //---------------------------------------------------------------------------
00177 
00178   virtual void initialSolve();
00179 
00183   virtual void resolve();
00184 
00187   void resolveForCost(int numretry);
00188 
00192   void resolveForRobustness(int numretry);
00193 
00195   virtual void branchAndBound()
00196   {
00197     throw SimpleError("Function not implemented for IpoptInterface","branchAndBound()");
00198   }
00200 
00201 
00202 
00203   //---------------------------------------------------------------------------
00205 
00206 
00207   virtual bool isAbandoned() const;
00209   virtual bool isProvenOptimal() const;
00211   virtual bool isProvenPrimalInfeasible() const;
00213   virtual bool isProvenDualInfeasible() const;
00215   virtual bool isPrimalObjectiveLimitReached() const;
00217   virtual bool isDualObjectiveLimitReached() const;
00219   virtual bool isIterationLimitReached() const;
00221   Ipopt::ApplicationReturnStatus getOptStatus() const
00222   {
00223     return optimization_status_;
00224   }
00225 
00227   void continuingOnAFailure()
00228   {
00229     hasContinuedAfterNlpFailure_ = true;
00230   }
00232   bool hasContinuedOnAFailure()
00233   {
00234     return hasContinuedAfterNlpFailure_;
00235   }
00237   void ignoreFailures()
00238   {
00239     pretendFailIsInfeasible_ = 2;
00240   }
00242   void forceInfeasible()
00243   {
00244     problem_->set_obj_value(1e200);
00245   }
00247   void forceBranchable()
00248   {
00249     problem_->set_obj_value(-1e200);
00250     problem_->force_fractionnal_sol();
00251   }
00253 
00254 
00255   //---------------------------------------------------------------------------
00271   // Set an integer parameter
00272   bool setIntParam(OsiIntParam key, int value);
00273   // Set an double parameter
00274   bool setDblParam(OsiDblParam key, double value);
00275   // Set a string parameter
00276   bool setStrParam(OsiStrParam key, const std::string & value);
00277   // Get an integer parameter
00278   bool getIntParam(OsiIntParam key, int& value) const;
00279   // Get an double parameter
00280   bool getDblParam(OsiDblParam key, double& value) const;
00281   // Get a string parameter
00282   bool getStrParam(OsiStrParam key, std::string& value) const;
00283 
00284   // Get the push values for starting point
00285   inline double getPushFact() const
00286   {
00287     return pushValue_;
00288   }
00289 
00291 
00292   //---------------------------------------------------------------------------
00307 
00308   virtual int getNumCols() const;
00309 
00311   virtual int getNumRows() const;
00312 
00314   const std::string * getVarNames() const;
00316   virtual const double * getColLower() const;
00317 
00319   virtual const double * getColUpper() const;
00320 
00330   virtual const char * getRowSense() const;
00331 
00340   virtual const double * getRightHandSide() const;
00341 
00350   virtual const double * getRowRange() const;
00351 
00353   virtual const double * getRowLower() const;
00354 
00356   virtual const double * getRowUpper() const;
00357 
00360   virtual double getObjSense() const
00361   {
00362     return 1;
00363   }
00364 
00366   virtual bool isContinuous(int colNumber) const;
00367 
00369   virtual bool isBinary(int columnNumber) const;
00370 
00375   virtual bool isInteger(int columnNumber) const;
00376 
00378   virtual bool isIntegerNonBinary(int columnNumber) const;
00379 
00381   virtual bool isFreeBinary(int columnNumber) const;
00382 
00384   virtual double getInfinity() const;
00385 
00387   const int * getPriorities() const
00388   {
00389     const Ipopt::TMINLP::BranchingInfo * branch = tminlp_->branchingInfo();
00390     if(branch)
00391       return branch->priorities;
00392     else return NULL;
00393   }
00395   const int * getBranchingDirections() const
00396   {
00397     const Ipopt::TMINLP::BranchingInfo * branch = tminlp_->branchingInfo();
00398     if(branch)
00399       return branch->branchingDirections;
00400     else return NULL;
00401   }
00402   const double * getUpPsCosts() const
00403   {
00404     const Ipopt::TMINLP::BranchingInfo * branch = tminlp_->branchingInfo();
00405     if(branch)
00406     return branch->upPsCosts;
00407     else return NULL;
00408   }
00409   const double * getDownPsCosts() const
00410   {
00411     const Ipopt::TMINLP::BranchingInfo * branch = tminlp_->branchingInfo();
00412     if(branch)
00413     return branch->downPsCosts;
00414     else return NULL;
00415   }
00416 
00417 
00419 
00422 
00423   virtual const double * getColSolution() const;
00424 
00431   virtual const double * getRowPrice() const;
00432 
00434   virtual const double * getReducedCost() const;
00435 
00438   virtual const double * getRowActivity() const;
00439 
00440 
00443   virtual int getIterationCount() const;
00444 
00446   int nCallOptimizeTNLP()
00447   {
00448     return nCallOptimizeTNLP_;
00449   }
00451   double totalNlpSolveTime()
00452   {
00453     return totalNlpSolveTime_;
00454   }
00456   int totalIterations()
00457   {
00458     return totalIterations_;
00459   }
00460 
00461 
00463   //-------------------------------------------------------------------------
00467 
00470   virtual void setColLower( int elementIndex, double elementValue );
00471 
00474   virtual void setColUpper( int elementIndex, double elementValue );
00475 
00476 
00477 
00480   virtual void setRowLower( int elementIndex, double elementValue );
00481 
00484   virtual void setRowUpper( int elementIndex, double elementValue );
00485 
00487   virtual void setRowType(int index, char sense, double rightHandSide,
00488       double range);
00489 
00490 
00495   virtual void setObjSense(double s);
00496 
00501   virtual void setColSolution(const double *colsol);
00502 
00510   virtual void setRowPrice(const double * rowprice);
00511 
00513 
00514 
00515   //---------------------------------------------------------------------------
00518 
00525   CoinWarmStart *getEmptyWarmStart () const;
00526 
00528   virtual CoinWarmStart* getWarmStart() const;
00529 
00532   virtual bool setWarmStart(const CoinWarmStart* warmstart);
00533 
00534 
00535   void setWarmStartOptions()
00536   {
00537     //    app_->Options()->SetIntegerValue("warm_start_init_point", 1);
00538     app_->Options()->SetStringValue("warm_start_init_point", "yes");
00539   }
00540   void unsetWarmStartOptions()
00541   {
00542     //app_->Options()->SetIntegerValue("warm_start_init_point", 1);
00543     app_->Options()->SetStringValue("warm_start_init_point", "no");
00544     problem_->resetStartingPoint();
00545   }
00546 
00547   void randomStartingPoint();
00548 
00549   //Returns true if a basis is available
00550   virtual bool basisIsAvailable() const
00551   {
00552     // Throw an exception
00553     throw SimpleError("Needs coding for this interface", "basisIsAvailable");
00554   }
00555 
00556 
00558 
00559   //-------------------------------------------------------------------------
00563   virtual void setContinuous(int index);
00565   virtual void setInteger(int index);
00567 
00568   //Set numIterationSuspect_
00569   void setNumIterationSuspect(int value)
00570   {
00571     numIterationSuspect_ = value;
00572   }
00573 
00579 
00582   virtual int getNumElements() const
00583   {
00584     return -1;
00585   }
00586 
00587 
00590   virtual const double * getObjCoefficients() const
00591   {
00592     if(!obj_)
00593       throw SimpleError("Ipopt model does not implement this function (function irelevant in an minlp).",
00594           "getObjCoefficients");
00595     return obj_;
00596   }
00597 
00600   virtual const CoinPackedMatrix * getMatrixByRow() const
00601   {
00602     throw CoinError("Ipopt model does not implement this function.",
00603         "getMatrixByRow()","IpoptInterface");
00604   }
00605 
00606 
00609   virtual const CoinPackedMatrix * getMatrixByCol() const
00610   {
00611     throw CoinError("Ipopt model does not implement this function.",
00612         "getMatrixByCol()","IpoptInterface");
00613   }
00614 
00617   virtual void setObjCoeff( int elementIndex, double elementValue )
00618   {
00619     throw CoinError("Ipopt model does not implement this function.",
00620         "setObjCoeff","IpoptInterface");
00621   }
00622 
00625   virtual void addCol(const CoinPackedVectorBase& vec,
00626       const double collb, const double colub,
00627       const double obj)
00628   {
00629     throw CoinError("Ipopt model does not implement this function.",
00630         "addCol","IpoptInterface");
00631   }
00634   virtual void deleteCols(const int num, const int * colIndices)
00635   {
00636     throw CoinError("Ipopt model does not implement this function.",
00637         "deleteCols","IpoptInterface");
00638   }
00639 
00642   virtual void addRow(const CoinPackedVectorBase& vec,
00643       const double rowlb, const double rowub)
00644   {
00645     throw CoinError("Ipopt model does not implement this function.",
00646         "addRow","IpoptInterface");
00647   }
00650   virtual void addRow(const CoinPackedVectorBase& vec,
00651       const char rowsen, const double rowrhs,
00652       const double rowrng)
00653   {
00654     throw CoinError("Ipopt model does not implement this function.",
00655         "addRow","IpoptInterface");
00656   }
00659   virtual void deleteRows(const int num, const int * rowIndices)
00660   {
00661     if(num>0)
00662       throw CoinError("Ipopt model does not implement this function.",
00663           "deleteRows","IpoptInterface");
00664   }
00665 
00668   virtual void loadProblem(const CoinPackedMatrix& matrix,
00669       const double* collb, const double* colub,
00670       const double* obj,
00671       const double* rowlb, const double* rowub)
00672   {
00673     throw CoinError("Ipopt model does not implement this function.",
00674         "loadProblem","IpoptInterface");
00675   }
00676 
00677 
00680   virtual void assignProblem(CoinPackedMatrix*& matrix,
00681       double*& collb, double*& colub, double*& obj,
00682       double*& rowlb, double*& rowub)
00683   {
00684     throw CoinError("Ipopt model does not implement this function.",
00685         "assignProblem","IpoptInterface");
00686   }
00687 
00690   virtual void loadProblem(const CoinPackedMatrix& matrix,
00691       const double* collb, const double* colub,
00692       const double* obj,
00693       const char* rowsen, const double* rowrhs,
00694       const double* rowrng)
00695   {
00696     throw CoinError("Ipopt model does not implement this function.",
00697         "loadProblem","IpoptInterface");
00698   }
00699 
00702   virtual void assignProblem(CoinPackedMatrix*& matrix,
00703       double*& collb, double*& colub, double*& obj,
00704       char*& rowsen, double*& rowrhs,
00705       double*& rowrng)
00706   {
00707     throw CoinError("Ipopt model does not implement this function.",
00708         "assignProblem","IpoptInterface");
00709   }
00710 
00711 
00714   virtual void loadProblem(const int numcols, const int numrows,
00715       const int* start, const int* index,
00716       const double* value,
00717       const double* collb, const double* colub,
00718       const double* obj,
00719       const double* rowlb, const double* rowub)
00720   {
00721     throw CoinError("Ipopt model does not implement this function.",
00722         "loadProblem","IpoptInterface");
00723   }
00724 
00727   virtual void loadProblem(const int numcols, const int numrows,
00728       const int* start, const int* index,
00729       const double* value,
00730       const double* collb, const double* colub,
00731       const double* obj,
00732       const char* rowsen, const double* rowrhs,
00733       const double* rowrng)
00734   {
00735     throw CoinError("Ipopt model does not implement this function.",
00736         "loadProblem","IpoptInterface");
00737   }
00738 
00741   virtual int readMps(const char *filename,
00742       const char *extension = "mps")
00743   {
00744     throw CoinError("Ipopt model does not implement this function.",
00745         "readMps","IpoptInterface");
00746   }
00747 
00748 
00751   virtual void writeMps(const char *filename,
00752       const char *extension = "mps",
00753       double objSense=0.0) const
00754   {
00755     throw CoinError("Ipopt model does not implement this function.",
00756         "writeMps","IpoptInterface");
00757   }
00758 
00760   virtual std::vector<double*> getDualRays(int maxNumRays) const
00761   {
00762     throw SimpleError("Ipopt model does not implement this function.",
00763         "getDualRays");
00764   }
00765 
00767   virtual std::vector<double*> getPrimalRays(int maxNumRays) const
00768   {
00769     throw CoinError("Ipopt model does not implement this function.",
00770         "getPrimalRays","IpoptInterface");
00771   }
00772 
00774 
00775   //---------------------------------------------------------------------------
00776 
00777 
00778 
00782   void turnOffIpoptOutput();
00783   void turnOnIpoptOutput();
00784 #ifdef COIN_HAS_GAMSLINKS
00785   void passInMessageHandler(CoinMessageHandler* messageHandler);
00786 #endif
00787 
00788 
00791 
00792   virtual double getObjValue() const;
00793 
00795 
00797   const Ipopt::TMINLP2TNLP * problem() const
00798   {
00799     return GetRawPtr(problem_);
00800   }
00801 
00802   const Ipopt::TMINLP * model() const
00803   {
00804     return GetRawPtr(tminlp_);
00805   }
00806   
00813   void extractLinearRelaxation(OsiSolverInterface &si, bool getObj = 1);
00814 
00817   void getOuterApproximation(OsiCuts &cs, bool getObj = 1);
00818 
00826   double getFeasibilityOuterApproximation(int n, const double * x_bar,const int *ind, OsiCuts &cs);
00828   inline bool cleanNnz(double &value, double colLower, double colUpper,
00829     double rowLower, double rowUpper, double colsol,
00830     double & lb, double &ub, double tiny, double veryTiny);
00832 
00833   double getConstraintViolation();
00834 
00835 //---------------------------------------------------------------------------
00836 protected:
00837 
00839   int initializeJacobianArrays();
00840 
00842 
00843   virtual std::string  appName()
00844   {
00845     return "bonmin";
00846   }
00848 
00849 
00850 
00852   void solveAndCheckErrors(bool doResolve, bool throwOnFailure,
00853       const char * whereFrom);
00854 
00855 
00858   virtual void applyRowCut( const OsiRowCut & rc )
00859   {
00860     throw SimpleError("Ipopt model does not implement this function.",
00861         "applyRowCut");
00862   }
00865   virtual void applyColCut( const OsiColCut & cc )
00866   {
00867     throw SimpleError("Ipopt model does not implement this function.",
00868         "applyColCut");
00869   }
00870 
00872   void readVarNames() const;
00873 
00875 
00879   Ipopt::SmartPtr<Ipopt::TMINLP> tminlp_;
00881   Ipopt::SmartPtr<Ipopt::TMINLP2TNLP> problem_;
00883   Ipopt::SmartPtr<Ipopt::IpoptApplication> app_;
00885 
00889   void freeCachedColRim();
00891   void freeCachedRowRim();
00893   void freeCachedData();
00896   void extractSenseRhsAndRange() const;
00898   mutable char    *rowsense_;
00899 
00901   mutable double  *rhs_;
00902 
00904   mutable double  *rowrange_;
00907   mutable double  *reducedCosts_;
00909   double OsiDualObjectiveLimit_;
00911   Ipopt::ApplicationReturnStatus optimization_status_;
00913   mutable std::string * varNames_;
00915   mutable bool hasVarNamesFile_;
00917 
00918   int nCallOptimizeTNLP_;
00920   double totalNlpSolveTime_;
00922   int totalIterations_;
00924   double maxRandomRadius_;
00926   double pushValue_;
00928   int numRetryInitial_;
00930   int numRetryResolve_;
00932   int numRetryUnsolved_;
00934   Messages ipoptIMessages_;
00938   int pretendFailIsInfeasible_;
00940   bool hasContinuedAfterNlpFailure_;
00943   int numIterationSuspect_ ;
00947   bool hasBeenOptimized_;
00955   int warmStartStrategy_;
00957   double * obj_;
00959   static bool hasPrintedOptions;
00960 
00962   Ipopt::SmartPtr<Ipopt::TNLP2FPNLP> feasibilityProblem_;
00963 
00964 
00968   int * jRow_;
00970   int * jCol_;
00972   double * jValues_;
00974   int nnz_jac;
00976 
00978   Ipopt::TMINLP::ConstraintType * constTypes_;
00982   int * constTypesNum_;
00984   int nLinear_;
00987   int nNonLinear_;
00989   double tiny_;
00991   double veryTiny_;
00993   bool firstSolve_;
00994 
00995 
00996 #ifdef COIN_HAS_GAMSLINKS
00997 
00998   Ipopt::SmartPtr<CoinMessageHandler2Journal> journal_;
00999 #endif
01000 };
01001 //A procedure to try to remove small coefficients in OA cuts (or make it non small
01002 inline
01003 bool IpoptInterface::cleanNnz(double &value, double colLower, double colUpper,
01004     double rowLower, double rowUpper, double colsol,
01005     double & lb, double &ub, double tiny, double veryTiny)
01006 {
01007   if(fabs(value)>= tiny) return 1;
01008 
01009   if(fabs(value)<veryTiny) return 0;//Take the risk?
01010 
01011   //try and remove
01012   double infty = 1e20;
01013   bool colUpBounded = colUpper < 10000;
01014   bool colLoBounded = colLower > -10000;
01015   bool rowNotLoBounded =  rowLower <= - infty;
01016   bool rowNotUpBounded = rowUpper >= infty;
01017   bool pos =  value > 0;
01018 
01019   if(!rowNotLoBounded && ! rowNotUpBounded)//would have to either choose side or duplicate cut
01020   {
01021     messageHandler()->message(WARN_NONCONVEX_OA, ipoptIMessages_)<<CoinMessageEol;
01022   }
01023 
01024   if(colLoBounded && pos && rowNotUpBounded) {
01025     lb += value * (colsol - colLower);
01026     value = 0;
01027     return 0;
01028   }
01029   else
01030     if(colLoBounded && !pos && rowNotLoBounded) {
01031       ub += value * (colsol - colLower);
01032       value = 0;
01033       return 0;
01034     }
01035     else
01036       if(colUpBounded && !pos && rowNotUpBounded) {
01037         lb += value * (colsol - colUpper);
01038         value = 0;
01039         return 0;
01040       }
01041       else
01042         if(colUpBounded && pos && rowNotLoBounded) {
01043           ub += value * (colsol - colUpper);
01044           value = 0;
01045           return 0;
01046         }
01047   //can not remove coefficient increase it to smallest non zero
01048   if(pos) value = tiny;
01049   else
01050     value = - tiny;
01051   return 1;
01052 }
01053 
01054 #endif

Generated on Fri May 16 21:06:00 2008 for Bonmin by  doxygen 1.4.7