/* $Id: CoinStructuredModel.hpp 1691 2014-03-19 12:43:56Z forrest $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). #ifndef CoinStructuredModel_H #define CoinStructuredModel_H #include "CoinModel.hpp" #include /** This is a model which is made up of Coin(Structured)Model blocks. */ typedef struct CoinModelInfo2 { int rowBlock; // Which row block int columnBlock; // Which column block char matrix; // nonzero if matrix exists char rhs; // nonzero if non default rhs exists char rowName; // nonzero if row names exists char integer; // nonzero if integer information exists char bounds; // nonzero if non default bounds/objective exists char columnName; // nonzero if column names exists CoinModelInfo2() : rowBlock(0), columnBlock(0), matrix(0), rhs(0), rowName(0), integer(0), bounds(0), columnName(0) {} } CoinModelBlockInfo; class CoinStructuredModel : public CoinBaseModel { public: /**@name Useful methods for building model */ //@{ /** add a block from a CoinModel using names given as parameters returns number of errors (e.g. both have objectives but not same) */ int addBlock(const std::string & rowBlock, const std::string & columnBlock, const CoinBaseModel & block); /** add a block from a CoinModel with names in model returns number of errors (e.g. both have objectives but not same) */ int addBlock(const CoinBaseModel & block); /** add a block from a CoinModel using names given as parameters returns number of errors (e.g. both have objectives but not same) This passes in block - structured model takes ownership */ int addBlock(const std::string & rowBlock, const std::string & columnBlock, CoinBaseModel * block); /** add a block using names */ int addBlock(const std::string & rowBlock, const std::string & columnBlock, const CoinPackedMatrix & matrix, const double * rowLower, const double * rowUpper, const double * columnLower, const double * columnUpper, const double * objective); /** Write the problem in MPS format to a file with the given filename. \param compression can be set to three values to indicate what kind of file should be written If the library was not compiled with the requested compression then writeMps falls back to writing a plain text file. \param formatType specifies the precision to used for values in the MPS file \param numberAcross specifies whether 1 or 2 (default) values should be specified on every data line in the MPS file. not const as may change model e.g. fill in default bounds */ int writeMps(const char *filename, int compression = 0, int formatType = 0, int numberAcross = 2, bool keepStrings=false) ; /// Read SMPS model int readSmps(const char *filename, bool keepNames = false, bool ignoreErrors = false); /** Decompose a CoinModel 1 - try D-W 2 - try Benders 3 - try Staircase Returns number of blocks or zero if no structure */ int decompose(const CoinModel &model,int type, int maxBlocks=50, const char ** starts=NULL); /** Decompose a model specified as arrays + CoinPackedMatrix 1 - try D-W 2 - try Benders 3 - try Staircase Returns number of blocks or zero if no structure */ int decompose(const CoinPackedMatrix & matrix, const double * rowLower, const double * rowUpper, const double * columnLower, const double * columnUpper, const double * objective, int type,int maxBlocks=50, int * starts=NULL, double objectiveOffset=0.0); //@} /**@name For getting information */ //@{ /// Return number of row blocks inline int numberRowBlocks() const { return numberRowBlocks_;} /// Return number of column blocks inline int numberColumnBlocks() const { return numberColumnBlocks_;} /// Return number of elementBlocks inline CoinBigIndex numberElementBlocks() const { return numberElementBlocks_;} /// Return number of elements CoinBigIndex numberElements() const; /// Return the i'th row block name inline const std::string & getRowBlock(int i) const { return rowBlockNames_[i];} /// Set i'th row block name inline void setRowBlock(int i,const std::string &name) { rowBlockNames_[i] = name;} /// Add or check a row block name and number of rows int addRowBlock(int numberRows,const std::string &name) ; /// Return a row block index given a row block name int rowBlock(const std::string &name) const; /// Return i'th the column block name inline const std::string & getColumnBlock(int i) const { return columnBlockNames_[i];} /// Set i'th column block name inline void setColumnBlock(int i,const std::string &name) { columnBlockNames_[i] = name;} /// Add or check a column block name and number of columns int addColumnBlock(int numberColumns,const std::string &name) ; /// Return a column block index given a column block name int columnBlock(const std::string &name) const; /// Return i'th block type inline const CoinModelBlockInfo & blockType(int i) const { return blockType_[i];} /// Return i'th block inline CoinBaseModel * block(int i) const { return blocks_[i];} /// Return block corresponding to row and column const CoinBaseModel * block(int row,int column) const; /// Return i'th block as CoinModel (or NULL) CoinModel * coinBlock(int i) const; /// Return block corresponding to row and column as CoinModel const CoinBaseModel * coinBlock(int row,int column) const; /// Return block number corresponding to row and column int blockIndex(int row,int column) const; /** Return model as a CoinModel block and fill in info structure and update counts */ CoinModel * coinModelBlock(CoinModelBlockInfo & info) ; /// Sets given block into coinModelBlocks_ void setCoinModel(CoinModel * block, int iBlock); /// Refresh info in blockType_ void refresh(int iBlock); /** Fill pointers corresponding to row and column */ CoinModelBlockInfo block(int row,int column, const double * & rowLower, const double * & rowUpper, const double * & columnLower, const double * & columnUpper, const double * & objective) const; /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore inline double optimizationDirection() const { return optimizationDirection_; } /// Set direction of optimization (1 - minimize, -1 - maximize, 0 - ignore inline void setOptimizationDirection(double value) { optimizationDirection_=value;} //@} /**@name Constructors, destructor */ //@{ /** Default constructor. */ CoinStructuredModel(); /** Read a problem in MPS format from the given filename. May try and decompose */ CoinStructuredModel(const char *fileName,int decompose=0, int maxBlocks=50); /** Destructor */ virtual ~CoinStructuredModel(); //@} /**@name Copy method */ //@{ /** The copy constructor. */ CoinStructuredModel(const CoinStructuredModel&); /// = CoinStructuredModel& operator=(const CoinStructuredModel&); /// Clone virtual CoinBaseModel * clone() const; //@} private: /** Fill in info structure and update counts Returns number of inconsistencies on border */ int fillInfo(CoinModelBlockInfo & info,const CoinModel * block); /** Fill in info structure and update counts */ void fillInfo(CoinModelBlockInfo & info,const CoinStructuredModel * block); /**@name Data members */ //@{ /// Current number of row blocks int numberRowBlocks_; /// Current number of column blocks int numberColumnBlocks_; /// Current number of element blocks int numberElementBlocks_; /// Maximum number of element blocks int maximumElementBlocks_; /// Rowblock name std::vector rowBlockNames_; /// Columnblock name std::vector columnBlockNames_; /// Blocks CoinBaseModel ** blocks_; /// CoinModel copies of blocks or NULL if original CoinModel CoinModel ** coinModelBlocks_; /// Which parts of model are set in block CoinModelBlockInfo * blockType_; //@} }; #endif