DecompApp.h

Go to the documentation of this file.
00001 
00002 //===========================================================================//
00003 // This file is part of the DIP Solver Framework.                            //
00004 //                                                                           //
00005 // DIP is distributed under the Eclipse Public License as part of the        //
00006 // COIN-OR repository (http://www.coin-or.org).                              //
00007 //                                                                           //
00008 // Author: Matthew Galati, SAS Institute Inc. (matthew.galati@sas.com)       //
00009 //                                                                           //
00010 // Conceptual Design: Matthew Galati, SAS Institute Inc.                     //
00011 //                    Ted Ralphs, Lehigh University                          //
00012 //                                                                           //
00013 // Copyright (C) 2002-2015, Lehigh University, Matthew Galati, Ted Ralphs    //
00014 // All Rights Reserved.                                                      //
00015 //===========================================================================//
00016 
00017 
00018 #ifndef DECOMP_APP_INCLUDED
00019 #define DECOMP_APP_INCLUDED
00020 
00021 //===========================================================================//
00022 #include "UtilParameters.h"
00023 #include "DecompParam.h"
00024 #include "DecompModel.h"
00025 #include "DecompSolution.h"
00026 #include "DecompConstraintSet.h"
00027 #include "CoinMpsIO.hpp"
00028 #include "CoinLpIO.hpp"
00029 
00030 extern "C" {
00031 #if defined (COIN_HAS_METIS)
00032 #include "hmetis.h"
00033 #endif
00034 }
00035 //===========================================================================//
00036 class DecompAlgo;
00037 
00038 //===========================================================================//
00049 //===========================================================================//
00050 class DecompApp {
00051 
00052 private:
00056    std::string m_classTag;
00057 
00058 protected:
00062    std::ostream* m_osLog;
00063 
00067    double m_bestKnownLB;
00068    double m_bestKnownUB;
00069 
00070 public:
00071 
00076    int NumBlocks;
00077 
00081    DecompParam m_param;
00082 
00086    const double* m_objective;
00087 
00088 
00092    DecompAppModel m_modelCore;
00093 
00097    std::map<int, DecompAppModel> m_modelRelax;
00098 
00102    std::map<int, std::vector<DecompAppModel> > m_modelRelaxNest;
00103 
00108    DecompAlgo* m_decompAlgo;
00109 
00110 
00111    /*
00112     *  The following definitiions was from MILPBlock
00113     *
00114     */
00115 
00117    CoinMpsIO m_mpsIO;
00118 
00120    CoinLpIO m_lpIO;
00121 
00124    const CoinPackedMatrix* m_matrix;
00125 
00126 
00129    DecompConstraintSet*   m_modelC;
00130    std::map<int, DecompConstraintSet*>  m_modelR;
00131 
00132 
00135    std::map<int, std::vector<int> > m_blocks;
00136 
00137 
00147    int m_threadIndex;
00148 
00149 public:
00158    void preprocess();
00159 
00163    void startupLog();
00164 
00165    //TODO:
00166    //base layer needs to do some kind of check to make sure this actually
00167    //got done - but also nice to have user version... so base createModel
00168    //and user uesrCreateModel() which is pure?, in base userCreateModel
00169    //gets called and checked that it returns good information
00170    int createModel();
00171 
00172    inline const double getBestKnownLB() const {
00173       return m_bestKnownLB;
00174    }
00175    inline const double getBestKnownUB() const {
00176       return m_bestKnownUB;
00177    }
00178 
00179    inline void setBestKnownLB(const double bestKnownLB) {
00180       m_bestKnownLB = bestKnownLB;
00181    }
00182    inline void setBestKnownUB(const double bestKnownUB) {
00183       m_bestKnownUB = bestKnownUB;
00184    }
00185 
00186 
00192    inline void setModelObjective(const double* objective, const
00193                                  int length) {
00194       assert(objective);
00195       double* obj = new double[length];
00196       memcpy(obj, objective, length * sizeof(double));
00197       m_objective = obj;
00198    }
00199 
00205    //TODO: having these implementations in the header makes
00206    // it harder to view this as an interface class - it is unclear
00207    // what the user must do vs can do
00208    inline void setModelCore(DecompConstraintSet* model,
00209                             const std::string          modelName) {
00210       assert(model);
00211 
00212       if (!model->hasPrepRun()) {
00213          model->prepareModel(true);
00214       }
00215 
00216       m_modelCore.setModel(model);
00217       m_modelCore.setModelName(modelName);
00218    }
00220    //TODO: change to setModelCore( ... )
00221    //  to long set of args of basic types - more like how Osi
00222    //  does loadProblem, etc... or juse use Osi as shell and accept
00223    //  an OsiSolverInterface?? or an OsiModel... is there one?
00224    //   maybe use CoinModel?? much cleaner?
00225    //at least set up an alternative to do it that way
00226    //still, this is still a function the user must call versus
00227    // a method they MUST override -which would fit more into the
00228    // framework concept - for e.g.,
00229    //virtual CoinModel * createModelCore() - the use must create a CoinModel
00230    //  or maybe a DecompModel which is derived from a CoinModel with
00231    //  whatever extra stuff might be needed - but I would try to avoid that
00232    //is it best to have it returned as return of function - forcing the
00233    //user to do it? or as arguments? and copy or assign pointers like
00234    //in SAS load problem design
00235 
00236 
00237 
00244    inline void setModelRelax(DecompConstraintSet* model,
00245                              const std::string          modelName = "",
00246                              const int             blockId   = 0) {
00247       if (model && !model->hasPrepRun()) {
00248          model->prepareModel();
00249       }
00250 
00251       //---
00252       //--- make sure this block has not been set yet
00253       //---
00254       std::map<int, DecompAppModel>::iterator mit = m_modelRelax.find(blockId);
00255 
00256       if (mit != m_modelRelax.end()) {
00257          std::cerr << "Block " << blockId << " relaxation has already been set. "
00258                    << "Only one relaxation definition can be used at one time."
00259                    << std::endl;
00260          throw UtilException("Multiple relaxation definitions",
00261                              "setModelRelax", "DecompApp");
00262       }
00263 
00264       DecompAppModel appModel(model, modelName, blockId);
00265       m_modelRelax.insert(std::make_pair(blockId, appModel));
00266    }
00267 
00272    inline void setModelRelaxNest(DecompConstraintSet* model,
00273                                  const std::string          modelName,
00274                                  const int             blockId = 0) {
00275       assert(model);
00276 
00277       if (!model->hasPrepRun()) {
00278          model->prepareModel();
00279       }
00280 
00281       DecompAppModel appModel(model, modelName, blockId);
00282       m_modelRelaxNest[blockId].push_back(appModel);
00283    }
00284 
00288    inline DecompAlgo* getDecompAlgo() const  {
00289       return m_decompAlgo;
00290    }
00291 
00292 
00298 public:
00314    virtual void initDualVector(std::vector<double>& dualVector) {}
00315 
00316 
00317    //TODO: change name - no other one is using APP, why here?
00340    //TODO: what is doxy tag for function return
00341    //TOOD: don't need numCols and tolZero should not be user overidable
00342    virtual bool APPisUserFeasible(const double* x,
00343                                   const int      numCols,
00344                                   const double   tolZero) {
00345       return true;
00346    };
00347 
00348    virtual int APPheuristics(const double*             xhat,
00349                              const double*             origCost,
00350                              std::vector<DecompSolution*>& xhatIPFeas) {
00351       return 0;
00352    }
00353 
00362    virtual const double* getDualForGenerateVars(const double* dual) {
00363       return 0;
00364    }
00365 
00366    virtual int generateInitVars(DecompVarList& initVars);
00367 
00368    virtual int generateCuts(const double*   x,
00369                             DecompCutList& newCuts);
00370 
00371    virtual void solveRelaxedWhich(std::vector<int>& blocksToSolve,
00372                                   std::map< int,
00373                   std::vector<double> >& userDualsByBlock) {
00374    };
00375 
00376    virtual DecompSolverStatus solveRelaxed(const int          whichBlock,
00377                                            const double*      redCostX,
00378                        const double       target,
00379                                            DecompVarList&     varList) {
00380       return DecompSolStatNoSolution;
00381    }
00382    virtual DecompSolverStatus solveRelaxedNest(const int          whichBlock,
00383                            const double*      redCostX,
00384                            const double       target,
00385                            DecompVarList&     varList) {
00386       return DecompSolStatNoSolution;
00387    }
00388 
00389 
00390    virtual void printOriginalColumn(const int   index,
00391                                     std::ostream*    os = &std::cout) const;
00392 
00393    //TODO: change api so colNames comes from modelCore if exists
00394    //  rather than - to simplify API
00395    virtual void printOriginalSolution(const int              n_cols,
00396                                       const std::vector<std::string>& colNames,
00397                                       const double*          solution,
00398                                       std::ostream*               os = &std::cout) const;
00399 
00406 public:
00407 
00409    virtual void initializeApp(UtilParameters& utilParam);
00410 
00413    void createModels();
00414 
00415    DecompConstraintSet* createModelPart(const int nRowsPart,
00416                                         const int* rowsPart);
00417 
00418    void createModelPart(DecompConstraintSet* model,
00419                         const int             nRowsPart,
00420                         const int*            rowsPart);
00421 
00422    void createModelPartSparse(DecompConstraintSet* model,
00423                               const int             nRowsPart,
00424                               const int*            rowsPart);
00425 
00426 
00427    void readInitSolutionFile(DecompVarList& initVars);
00428 
00430    void readBlockFile();
00431 
00433    const CoinPackedMatrix*  readProblem(UtilParameters& utilParam);
00434 
00435 
00438    void singlyBorderStructureDetection();
00439 
00441    void findActiveColumns(const std::vector<int>& rowsPart,
00442                           std::set<int>&           activeColsSet);
00443 
00446    const std::string getInstanceName() {
00447       return m_param.Instance;
00448    }
00449    /*
00450    void  HMETIS_PartKway(int nvtxs, int nhedges, int *vwgts, int *eptr,
00451           int *eind, int *hewgts, int nparts, int ubfactor,
00452           int * options, int * part, int *edgecut);
00453 
00454    void  HMETIS_PartRecursive(int nvtxs, int nhedges, int *vwgts, int *eptr,
00455            int *eind, int *hewgts, int nparts, int ubfactor,
00456            int * options, int * part, int *edgecut);
00457    */
00458 
00459 
00460 
00461 
00462 public:
00470    DecompApp(UtilParameters& utilParam) :
00471       m_classTag   ("D-APP"),
00472       m_osLog      (&std::cout  ),
00473       m_bestKnownLB(-1e75  ),
00474       m_bestKnownUB( 1e75  ),
00475       NumBlocks    (  0    ),
00476       m_objective  ( NULL  ),
00477       m_matrix     ( NULL  ),
00478       m_modelC     ( NULL  ),
00479       m_threadIndex(  0    ) {
00480       m_param.getSettings(utilParam);
00481       startupLog();
00482    };
00483 
00484 
00485    DecompApp() :
00486       m_classTag   ("D-APP"),
00487       m_osLog      (&std::cout  ),
00488       m_bestKnownLB(-1e75  ),
00489       m_bestKnownUB( 1e75  ),
00490       NumBlocks    ( 0     ),
00491       m_objective  ( NULL  ),
00492       m_matrix     ( NULL  ),
00493       m_modelC     ( NULL  ),
00494       m_threadIndex(  0    ) {
00495       //---
00496       //--- comment these functions, which were used in
00497       //--- MILPBlock, otherwise, conflict occurs in building
00498       //--- individual examples
00499       //     m_param.getSettings(utilParam);
00500       //     initializeApp(utilParam);
00501       //     startupLog();
00502    };
00503 
00507    virtual ~DecompApp() {
00508       UTIL_DELARR(m_objective);
00509       UtilDeleteMapPtr(m_modelR);
00510       UTIL_DELPTR(m_modelC);
00511    };
00512 };
00513 
00514 #endif

Generated on 5 Apr 2015 for Dip-All by  doxygen 1.6.1