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?
00338    //TODO: what is doxy tag for function return
00339    //TOOD: don't need numCols and tolZero should not be user overidable
00340    virtual bool APPisUserFeasible(const double* x,
00341                                   const int      numCols,
00342                                   const double   tolZero) {
00343       return true;
00344    };
00345 
00346    virtual int APPheuristics(const double*             xhat,
00347                              const double*             origCost,
00348                              std::vector<DecompSolution*>& xhatIPFeas) {
00349       return 0;
00350    }
00351 
00360    virtual const double* getDualForGenerateVars(const double* dual) {
00361       return 0;
00362    }
00363 
00364    virtual int generateInitVars(DecompVarList& initVars);
00365 
00366    virtual int generateCuts(const double*   x,
00367                             DecompCutList& newCuts);
00368 
00369    virtual void solveRelaxedWhich(std::vector<int>& blocksToSolve,
00370                                   std::map< int,
00371                   std::vector<double> >& userDualsByBlock) {
00372    };
00373 
00374    virtual DecompSolverStatus solveRelaxed(const int          whichBlock,
00375                                            const double*      redCostX,
00376                        const double       target,
00377                                            DecompVarList&     varList) {
00378       return DecompSolStatNoSolution;
00379    }
00380    virtual DecompSolverStatus solveRelaxedNest(const int          whichBlock,
00381                            const double*      redCostX,
00382                            const double       target,
00383                            DecompVarList&     varList) {
00384       return DecompSolStatNoSolution;
00385    }
00386 
00387 
00388    virtual void printOriginalColumn(const int   index,
00389                                     std::ostream*    os = &std::cout) const;
00390 
00391    //TODO: change api so colNames comes from modelCore if exists
00392    //  rather than - to simplify API
00393    virtual void printOriginalSolution(const int              n_cols,
00394                                       const std::vector<std::string>& colNames,
00395                                       const double*          solution,
00396                                       std::ostream*               os = &std::cout) const;
00397 
00404 public:
00405 
00407    virtual void initializeApp(UtilParameters& utilParam);
00408 
00411    void createModels();
00412 
00413    DecompConstraintSet* createModelPart(const int nRowsPart,
00414                                         const int* rowsPart);
00415 
00416    void createModelPart(DecompConstraintSet* model,
00417                         const int             nRowsPart,
00418                         const int*            rowsPart);
00419 
00420    void createModelPartSparse(DecompConstraintSet* model,
00421                               const int             nRowsPart,
00422                               const int*            rowsPart);
00423 
00424 
00425    void readInitSolutionFile(DecompVarList& initVars);
00426 
00428    void readBlockFile();
00429 
00431    const CoinPackedMatrix*  readProblem(UtilParameters& utilParam);
00432 
00433 
00436    void singlyBorderStructureDetection();
00437 
00439    void findActiveColumns(const std::vector<int>& rowsPart,
00440                           std::set<int>&           activeColsSet);
00441 
00444    const std::string getInstanceName() {
00445       return m_param.Instance;
00446    }
00447    /*
00448    void  HMETIS_PartKway(int nvtxs, int nhedges, int *vwgts, int *eptr,
00449           int *eind, int *hewgts, int nparts, int ubfactor,
00450           int * options, int * part, int *edgecut);
00451 
00452    void  HMETIS_PartRecursive(int nvtxs, int nhedges, int *vwgts, int *eptr,
00453            int *eind, int *hewgts, int nparts, int ubfactor,
00454            int * options, int * part, int *edgecut);
00455    */
00456 
00457 
00458 
00459 
00460 public:
00468    DecompApp(UtilParameters& utilParam) :
00469       m_classTag   ("D-APP"),
00470       m_osLog      (&std::cout  ),
00471       m_bestKnownLB(-1e75  ),
00472       m_bestKnownUB( 1e75  ),
00473       NumBlocks    (  0    ),
00474       m_objective  ( NULL  ),
00475       m_matrix     ( NULL  ),
00476       m_modelC     ( NULL  ),
00477       m_threadIndex(  0    ) {
00478       m_param.getSettings(utilParam);
00479       startupLog();
00480    };
00481 
00482 
00483    DecompApp() :
00484       m_classTag   ("D-APP"),
00485       m_osLog      (&std::cout  ),
00486       m_bestKnownLB(-1e75  ),
00487       m_bestKnownUB( 1e75  ),
00488       NumBlocks    ( 0     ),
00489       m_objective  ( NULL  ),
00490       m_matrix     ( NULL  ),
00491       m_modelC     ( NULL  ),
00492       m_threadIndex(  0    ) {
00493       //---
00494       //--- comment these functions, which were used in
00495       //--- MILPBlock, otherwise, conflict occurs in building
00496       //--- individual examples
00497       //     m_param.getSettings(utilParam);
00498       //     initializeApp(utilParam);
00499       //     startupLog();
00500    };
00501 
00505    virtual ~DecompApp() {
00506       UTIL_DELARR(m_objective);
00507       UtilDeleteMapPtr(m_modelR);
00508       UTIL_DELPTR(m_modelC);
00509    };
00510 };
00511 
00512 #endif

Generated on 12 Mar 2015 for Dip-All by  doxygen 1.6.1