#ifndef CPLEXMODEL_H #define CPLEXMODEL_H #include #include #include #ifndef NO_CPLEX #include #else #include #endif /** @author Antoine Rozenknop */ struct CPlexFailed : public std::string { CPlexFailed(std::string msg, void * env, int cpx_status); CPlexFailed(); }; class CPlexModel{ public: /// type ObjectiveSense : type de problème (maximisation ou minimisation) enum ObjectiveSense { Minimisation, Maximisation }; enum ProblemType { Linear, MixedInteger }; enum ParallelMode { Default, None, Opportunistic }; enum OptionDouble { Time }; /// constructeur CPlexModel(std::string nom, ObjectiveSense obj_sense = Minimisation, ProblemType = Linear, bool internal_silent = true, bool silent = true, bool writeToFile = false, bool with_names = false ); /// destructer ~CPlexModel(); static std::string errorstring(void * env, int cpx_status); static std::string statusstring(void * env, int cpx_status); /// type Sense : opérateur de comparaison pour les contraintes enum Sense { Equals = 'E', GreaterThan = 'G', LowerThan = 'L', Range = 'R' }; /// type Type : type de variables à chercher (binaire ou continue) enum Type { Binary = 'B', Continuous = 'C' }; /// appelle Cplex et renvoie la valeur de la fonction objectif double resolution(); /// rappelle Cplex après ajout de nouvelles colonnes et renvoie la valeur de la fonction objectif double newcolumns_resolution(); /// récupère la valeur des variables d'une zone horizontale std::vector getResult(std::string zoneH); /// récupère la valeur des coûts réduites d'une zone horizontale std::vector getReducedCosts(std::string zoneH); /// récupère la valeur des variables duales d'une zone verticale std::vector getDuals(std::string zoneV); /// récupère la valeur de la fonction objectif double getObjectiveValue() const { return cpx_objval ; } /// définition de zones /// ces deux fonctions renvoient l'index de la zone créée size_t addZoneVerticale ( std::string nom, size_t taille ); size_t addZoneHorizontale( std::string nom, size_t taille ); /// option void setOption( ParallelMode ) {} /// suppression d'une ou plusieurs colonnes (zone horizontale) void removeZoneHorizontale ( std::string nom ); /// fixage de la zone avant d'entrer des valeurs inline void setZoneVerticale ( std::string nom ); inline void setZoneHorizontale( std::string nom ); /// ajout d'éléments à Z inline void addToZ( size_t row, size_t col, double val ); /// ajout d'éléments à la partie droite inline void addToRHS( size_t row, Sense comp, double val, double range = 0 ); /// ajout des bornes et du type des variables et de leur coefficient dans la fonction objectif inline void addToObj( size_t col, double min, double max, Type type, double coeff ); protected: /// réintialisation de l'environnement de cplex void FreeCplex(); /// zones std::map m_zoneVerticale ; std::map m_zoneHorizontale ; std::map m_taille_zoneVerticale ; std::map m_taille_zoneHorizontale ; size_t m_debut_zoneH ; size_t m_debut_zoneV ; std::vector m_noms_variables ; std::vector m_noms_contraintes ; /// matrice Z size_t m_taille_Z ; size_t m_taille_solvedZ ; std::vector< std::map > m_Z ; /// partie droite std::vector m_comp ; std::vector m_rhs ; std::vector m_range; /// variables std::vector m_min ; std::vector m_max ; std::vector m_type ; std::vector m_coeff_objectif ; /// communication avec cplex virtual void setProblemData() ; virtual void transferProblemData() ; CPXENVptr env ; CPXLPptr lp ; bool cpx_internal_silent ; bool cpx_silent ; bool m_writeToFile ; bool m_with_names ; std::string cpx_probname ; int cpx_numcols ; int cpx_numrows ; int cpx_solvedcols ; int cpx_objsense ; ProblemType cpx_problemtype ; std::vector cpx_matbeg ; std::vector cpx_matcnt ; std::vector cpx_matind ; std::vector cpx_matval ; /// résultat : valeur de la fonction objectif double cpx_objval ; /// résultat : valeurs des variables std::vector cpx_vars ; /// résultat : valeurs des variables duales std::vector cpx_duals ; /// résultat : valeurs des coûts réduits std::vector cpx_cr ; }; /* implantation des fonctions inline de remplissage du modèle */ /// fixage de la zone avant d'entrer des valeurs inline void CPlexModel::setZoneVerticale ( std::string nom ) { if (m_zoneVerticale.find(nom)==m_zoneVerticale.end()) throw std::string("zone inexistante"); m_debut_zoneV = m_zoneVerticale[nom] ; } inline void CPlexModel::setZoneHorizontale( std::string nom ) { if (m_zoneHorizontale.find(nom)==m_zoneHorizontale.end()) throw std::string("zone inexistante"); m_debut_zoneH = m_zoneHorizontale[nom] ; } inline void CPlexModel::addToZ( size_t row, size_t col, double val ) { m_taille_Z ++ ; m_Z [m_debut_zoneH + col] [m_debut_zoneV + row] = val ; } inline void CPlexModel::addToRHS( size_t row, Sense comp, double val, double range ) { m_comp [m_debut_zoneV + row] = comp ; m_rhs [m_debut_zoneV + row] = val ; if (comp==Range) m_range[m_debut_zoneV + row] = range; } inline void CPlexModel::addToObj( size_t col, double min, double max, Type type, double coeff ) { m_min [m_debut_zoneH + col] = min ; m_max [m_debut_zoneH + col] = max ; m_type [m_debut_zoneH + col] = type ; m_coeff_objectif [m_debut_zoneH + col] = coeff ; } #endif