From cbdfb636230cd034af0351d85f344ca51c0ac903 Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Wed, 9 Aug 2023 10:54:51 +0200 Subject: [PATCH 01/17] update constraint pattern --- src/solver/infeasible-problem-analysis/problem.cpp | 4 ++-- src/solver/infeasible-problem-analysis/problem.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/solver/infeasible-problem-analysis/problem.cpp b/src/solver/infeasible-problem-analysis/problem.cpp index f1178aeedb..d6ca610f9a 100644 --- a/src/solver/infeasible-problem-analysis/problem.cpp +++ b/src/solver/infeasible-problem-analysis/problem.cpp @@ -25,11 +25,11 @@ void InfeasibleProblemAnalysis::addSlackVariables() */ const unsigned int selectedConstraintsInverseRatio = 3; mSlackVariables.reserve(mSolver->NumConstraints() / selectedConstraintsInverseRatio); - std::regex rgx(mPattern); + std::regex rgx(constraint_name_pattern); const double infinity = MPSolver::infinity(); for (MPConstraint* constraint : mSolver->constraints()) { - if (std::regex_match(constraint->name(), rgx)) + if (std::regex_search(constraint->name(), rgx)) { if (constraint->lb() != -infinity) { diff --git a/src/solver/infeasible-problem-analysis/problem.h b/src/solver/infeasible-problem-analysis/problem.h index 209f8eda7d..92edde4294 100644 --- a/src/solver/infeasible-problem-analysis/problem.h +++ b/src/solver/infeasible-problem-analysis/problem.h @@ -25,7 +25,8 @@ class InfeasibleProblemAnalysis std::unique_ptr mSolver; std::vector mSlackVariables; - const std::string mPattern = ".+::.+"; + const std::string constraint_name_pattern = "^AreaHydroLevel::|::hourly::|::daily::|::weekly:|^FictiveLoads::"; + }; } // namespace Optimization } // namespace Antares From 2fb18b54ba0d9bc2905a46fe83bc849cdf96a0af Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Wed, 9 Aug 2023 16:18:00 +0200 Subject: [PATCH 02/17] fix prettyprint of suspicious constraints --- .../constraint.cpp | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/solver/infeasible-problem-analysis/constraint.cpp b/src/solver/infeasible-problem-analysis/constraint.cpp index 9d26f951aa..467072cb35 100644 --- a/src/solver/infeasible-problem-analysis/constraint.cpp +++ b/src/solver/infeasible-problem-analysis/constraint.cpp @@ -1,6 +1,7 @@ #include #include "constraint.h" +#include namespace Antares { @@ -38,7 +39,17 @@ double Constraint::getSlackValue() const { return mSlackValue; } - +std::vector split(const std::string& s, char delimiter) +{ + std::vector tokens; + std::string token; + std::istringstream tokenStream(s); + while (std::getline(tokenStream, token, delimiter)) + { + tokens.push_back(token); + } + return tokens; +} std::string Constraint::getAreaName() const { if ((getType() == ConstraintType::binding_constraint_hourly) @@ -47,7 +58,7 @@ std::string Constraint::getAreaName() const { return ""; } - return mItems.at(2); + return split(split(mItems.at(1), '<')[1], '>')[1]; } std::string Constraint::getTimeStepInYear() const @@ -65,35 +76,26 @@ std::string Constraint::getTimeStepInYear() const } } -static ConstraintType bindingConstraintPeriodicity(const std::string& in) +ConstraintType Constraint::getType() const { - if (in == "hourly") + assert(mItems.size() > 1); + if (mItems.at(1) == "hourly") { return ConstraintType::binding_constraint_hourly; } - if (in == "daily") + if (mItems.at(1) == "daily") { return ConstraintType::binding_constraint_daily; } - if (in == "weekly") + if (mItems.at(1) == "weekly") { return ConstraintType::binding_constraint_weekly; } - return ConstraintType::none; -} - -ConstraintType Constraint::getType() const -{ - assert(mItems.size() > 1); - if (mItems.at(0) == "bc") - { - return bindingConstraintPeriodicity(mItems.at(1)); - } - if (mItems.at(0) == "fict_load") + if (mItems.at(0) == "FictiveLoads") { return ConstraintType::fictitious_load; } - if (mItems.at(0) == "hydro_level") + if (mItems.at(0) == "AreaHydroLevel") { return ConstraintType::hydro_reservoir_level; } @@ -106,9 +108,8 @@ std::string Constraint::getBindingConstraintName() const { case ConstraintType::binding_constraint_hourly: case ConstraintType::binding_constraint_daily: - return mItems.at(3); case ConstraintType::binding_constraint_weekly: - return mItems.at(2); + return mItems.at(0); default: return ""; } From 566aed837333c577ef9715f9ae0dcd2bb3e63432 Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Wed, 9 Aug 2023 16:57:42 +0200 Subject: [PATCH 03/17] parse time step --- src/solver/infeasible-problem-analysis/constraint.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/solver/infeasible-problem-analysis/constraint.cpp b/src/solver/infeasible-problem-analysis/constraint.cpp index 467072cb35..1e0204d8a3 100644 --- a/src/solver/infeasible-problem-analysis/constraint.cpp +++ b/src/solver/infeasible-problem-analysis/constraint.cpp @@ -50,6 +50,11 @@ std::vector split(const std::string& s, char delimiter) } return tokens; } + +std::string StringBetweenAngleBrackets(const std::string& str){ + return split(split(str, '<')[1], '>')[0]; +} + std::string Constraint::getAreaName() const { if ((getType() == ConstraintType::binding_constraint_hourly) @@ -58,7 +63,7 @@ std::string Constraint::getAreaName() const { return ""; } - return split(split(mItems.at(1), '<')[1], '>')[1]; + return StringBetweenAngleBrackets(mItems.at(1)); } std::string Constraint::getTimeStepInYear() const @@ -67,10 +72,9 @@ std::string Constraint::getTimeStepInYear() const { case ConstraintType::binding_constraint_hourly: case ConstraintType::binding_constraint_daily: - return mItems.at(2); case ConstraintType::fictitious_load: case ConstraintType::hydro_reservoir_level: - return mItems.at(1); + return StringBetweenAngleBrackets (mItems.at(mItems.size()-2)); default: return "-1"; } From 12436303edba0131611dc30e56f86a7c442c1faa Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Thu, 10 Aug 2023 09:59:08 +0200 Subject: [PATCH 04/17] update regex --- src/solver/infeasible-problem-analysis/problem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solver/infeasible-problem-analysis/problem.h b/src/solver/infeasible-problem-analysis/problem.h index 92edde4294..d0e277492a 100644 --- a/src/solver/infeasible-problem-analysis/problem.h +++ b/src/solver/infeasible-problem-analysis/problem.h @@ -25,7 +25,7 @@ class InfeasibleProblemAnalysis std::unique_ptr mSolver; std::vector mSlackVariables; - const std::string constraint_name_pattern = "^AreaHydroLevel::|::hourly::|::daily::|::weekly:|^FictiveLoads::"; + const std::string constraint_name_pattern = "^AreaHydroLevel::|::hourly::|::daily::|::weekly::|^FictiveLoads::"; }; } // namespace Optimization From 0988ebbe8436228d2ae803021b3c1b93788eb547 Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Tue, 22 Aug 2023 11:05:23 +0200 Subject: [PATCH 05/17] always name antares problems --- ...nstruction_contraintes_couts_demarrage.cpp | 3 +- ...n_matrice_des_contraintes_cas_lineaire.cpp | 3 +- ...onstruction_variables_couts_demarrages.cpp | 2 +- ...truction_variables_optimisees_lineaire.cpp | 2 +- src/solver/optimisation/opt_rename_problem.h | 14 ++++----- src/solver/utils/mps_utils.cpp | 13 ++------ src/solver/utils/named_problem.h | 30 +++++++++++++++++++ src/solver/utils/ortools_utils.cpp | 4 +-- 8 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/solver/optimisation/opt_construction_contraintes_couts_demarrage.cpp b/src/solver/optimisation/opt_construction_contraintes_couts_demarrage.cpp index e876699fc2..794919f1bd 100644 --- a/src/solver/optimisation/opt_construction_contraintes_couts_demarrage.cpp +++ b/src/solver/optimisation/opt_construction_contraintes_couts_demarrage.cpp @@ -46,8 +46,7 @@ void OPT_ConstruireLaMatriceDesContraintesDuProblemeLineaireCoutsDeDemarrage( std::vector& Pi = ProblemeAResoudre->Pi; std::vector& Colonne = ProblemeAResoudre->Colonne; - ConstraintNamer constraintNamer(ProblemeAResoudre->NomDesContraintes, - problemeHebdo->NamedProblems); + ConstraintNamer constraintNamer(ProblemeAResoudre->NomDesContraintes); int nbTermesContraintesPourLesCoutsDeDemarrage = 0; for (int pays = 0; pays < problemeHebdo->NombreDePays; pays++) { diff --git a/src/solver/optimisation/opt_construction_matrice_des_contraintes_cas_lineaire.cpp b/src/solver/optimisation/opt_construction_matrice_des_contraintes_cas_lineaire.cpp index 73c5f2be00..6d26e096b5 100644 --- a/src/solver/optimisation/opt_construction_matrice_des_contraintes_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_construction_matrice_des_contraintes_cas_lineaire.cpp @@ -170,8 +170,7 @@ void OPT_ConstruireLaMatriceDesContraintesDuProblemeLineaire(PROBLEME_HEBDO* pro ProblemeAResoudre->NombreDeContraintes = 0; ProblemeAResoudre->NombreDeTermesDansLaMatriceDesContraintes = 0; - ConstraintNamer constraintNamer(ProblemeAResoudre->NomDesContraintes, - problemeHebdo->NamedProblems); + ConstraintNamer constraintNamer(ProblemeAResoudre->NomDesContraintes); for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) { diff --git a/src/solver/optimisation/opt_construction_variables_couts_demarrages.cpp b/src/solver/optimisation/opt_construction_variables_couts_demarrages.cpp index ffbad62e33..75d49f975c 100644 --- a/src/solver/optimisation/opt_construction_variables_couts_demarrages.cpp +++ b/src/solver/optimisation/opt_construction_variables_couts_demarrages.cpp @@ -43,7 +43,7 @@ void OPT_ConstruireLaListeDesVariablesOptimiseesDuProblemeLineaireCoutsDeDemarra int nombreDePasDeTempsPourUneOptimisation = problemeHebdo->NombreDePasDeTempsPourUneOptimisation; int nombreDeVariables = ProblemeAResoudre->NombreDeVariables; - VariableNamer variableNamer(ProblemeAResoudre->NomDesVariables, problemeHebdo->NamedProblems); + VariableNamer variableNamer(ProblemeAResoudre->NomDesVariables); for (int pays = 0; pays < problemeHebdo->NombreDePays; pays++) { variableNamer.UpdateArea(problemeHebdo->NomsDesPays[pays]); diff --git a/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp b/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp index 683eb734d9..95b3f0186e 100644 --- a/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp +++ b/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp @@ -38,7 +38,7 @@ void OPT_ConstruireLaListeDesVariablesOptimiseesDuProblemeLineaire(PROBLEME_HEBD int NombreDePasDeTempsPourUneOptimisation = problemeHebdo->NombreDePasDeTempsPourUneOptimisation; int NombreDeVariables = 0; - VariableNamer variableNamer(ProblemeAResoudre->NomDesVariables, problemeHebdo->NamedProblems); + VariableNamer variableNamer(ProblemeAResoudre->NomDesVariables); for (int pdt = 0; pdt < NombreDePasDeTempsPourUneOptimisation; pdt++) { diff --git a/src/solver/optimisation/opt_rename_problem.h b/src/solver/optimisation/opt_rename_problem.h index 6c19a3e415..bd392a1ba5 100644 --- a/src/solver/optimisation/opt_rename_problem.h +++ b/src/solver/optimisation/opt_rename_problem.h @@ -8,29 +8,25 @@ const std::string AREA_SEP = "$$"; class TargetVectorUpdater { public: - TargetVectorUpdater(bool isRenamingProcessed, std::vector& target) : - target_(target), isRenamingProcessed_(isRenamingProcessed) + TargetVectorUpdater(std::vector& target) : + target_(target) { } void UpdateTargetAtIndex(const std::string& full_name, unsigned int index) { - if (isRenamingProcessed_) - { - target_[index] = full_name; - } + target_[index] = full_name; } private: std::vector& target_; - bool isRenamingProcessed_; }; class Namer { public: - Namer(std::vector& target, bool namedProblems) : - targetUpdater_(namedProblems, target) + Namer(std::vector& target) : + targetUpdater_(target) { } diff --git a/src/solver/utils/mps_utils.cpp b/src/solver/utils/mps_utils.cpp index 811d0e6556..3466e031f8 100644 --- a/src/solver/utils/mps_utils.cpp +++ b/src/solver/utils/mps_utils.cpp @@ -55,15 +55,6 @@ using namespace Yuni; #define SEP IO::Separator -static char** VectorOfStringToCharPP(std::vector& in, std::vector& pointerVec) -{ - std::transform(in.begin(), - in.end(), - std::back_inserter(pointerVec), - [](std::string& str) { return str.empty() ? nullptr : str.data(); }); - return pointerVec.data(); -} - class ProblemConverter { public: @@ -95,8 +86,8 @@ class ProblemConverter dest->SensDeLaContrainte = src->Sens; // Names - dest->LabelDeLaVariable = VectorOfStringToCharPP(src->NomDesVariables, mVariableNames); - dest->LabelDeLaContrainte = VectorOfStringToCharPP(src->NomDesContraintes, mConstraintNames); + dest->LabelDeLaVariable = src->VariableNamesAsCharPP(mVariableNames); + dest->LabelDeLaContrainte = src->ConstraintNamesAsCharPP(mConstraintNames); } private: diff --git a/src/solver/utils/named_problem.h b/src/solver/utils/named_problem.h index 9c393b9a07..031dea0dad 100644 --- a/src/solver/utils/named_problem.h +++ b/src/solver/utils/named_problem.h @@ -5,11 +5,22 @@ #include #include +#include +#include namespace Antares { namespace Optimization { +static inline char** VectorOfStringToCharPP(std::vector& in, + std::vector& pointerVec) +{ + std::transform(in.begin(), + in.end(), + std::back_inserter(pointerVec), + [](std::string& str) { return str.empty() ? nullptr : str.data(); }); + return pointerVec.data(); +} struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE { public: @@ -18,13 +29,32 @@ struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE std::vector& StatutDesVariables, std::vector& StatutDesContraintes); +private: std::vector NomDesVariables; std::vector NomDesContraintes; + +public: std::vector& StatutDesVariables; std::vector& StatutDesContraintes; bool isMIP() const; bool basisExists() const; + char** VariableNamesAsCharPP(std::vector& pointerVec) + { + return VectorOfStringToCharPP(NomDesVariables, pointerVec); + } + char** ConstraintNamesAsCharPP(std::vector& pointerVec) + { + return VectorOfStringToCharPP(NomDesContraintes, pointerVec); + } + const std::vector& VariableNames() const + { + return NomDesVariables; + } + const std::vector& ConstraintNames() const + { + return NomDesContraintes; + } }; } // namespace Optimization } // namespace Antares diff --git a/src/solver/utils/ortools_utils.cpp b/src/solver/utils/ortools_utils.cpp index ce823fc597..efb344ccff 100644 --- a/src/solver/utils/ortools_utils.cpp +++ b/src/solver/utils/ortools_utils.cpp @@ -152,14 +152,14 @@ MPSolver* convert_to_MPSolver( problemeSimplexe->Xmax, problemeSimplexe->CoutLineaire, problemeSimplexe->NombreDeVariables, - problemeSimplexe->NomDesVariables); + problemeSimplexe->VariableNames()); // Create constraints and set coefs transferRows(solver, problemeSimplexe->SecondMembre, problemeSimplexe->Sens, problemeSimplexe->NombreDeContraintes, - problemeSimplexe->NomDesContraintes); + problemeSimplexe->ConstraintNames()); transferMatrix(solver, problemeSimplexe->IndicesDebutDeLigne, problemeSimplexe->NombreDeTermesDesLignes, From 5423a62d994a8537afe46d5fb4e504ba5a6d4c15 Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Tue, 22 Aug 2023 11:22:58 +0200 Subject: [PATCH 06/17] named problems with unnamed mps --- .../opt_appel_solveur_lineaire.cpp | 3 ++- src/solver/utils/named_problem.cpp | 6 +++-- src/solver/utils/named_problem.h | 26 ++++++++++++++++--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/solver/optimisation/opt_appel_solveur_lineaire.cpp b/src/solver/optimisation/opt_appel_solveur_lineaire.cpp index d00baced91..1d1b915551 100644 --- a/src/solver/optimisation/opt_appel_solveur_lineaire.cpp +++ b/src/solver/optimisation/opt_appel_solveur_lineaire.cpp @@ -99,7 +99,8 @@ bool OPT_AppelDuSimplexe(const OptimizationOptions& options, Optimization::PROBLEME_SIMPLEXE_NOMME Probleme(ProblemeAResoudre->NomDesVariables, ProblemeAResoudre->NomDesContraintes, ProblemeAResoudre->StatutDesVariables, - ProblemeAResoudre->StatutDesContraintes); + ProblemeAResoudre->StatutDesContraintes, + problemeHebdo->NamedProblems); bool PremierPassage = true; auto ProbSpx diff --git a/src/solver/utils/named_problem.cpp b/src/solver/utils/named_problem.cpp index 7f22c0c02e..bf87230306 100644 --- a/src/solver/utils/named_problem.cpp +++ b/src/solver/utils/named_problem.cpp @@ -10,12 +10,14 @@ namespace Optimization PROBLEME_SIMPLEXE_NOMME::PROBLEME_SIMPLEXE_NOMME(const std::vector& NomDesVariables, const std::vector& NomDesContraintes, std::vector& StatutDesVariables, - std::vector& StatutDesContraintes) : + std::vector& StatutDesContraintes, + bool UseNamedProblems) : NomDesVariables(NomDesVariables), NomDesContraintes(NomDesContraintes), StatutDesVariables(StatutDesVariables), - StatutDesContraintes(StatutDesContraintes) + StatutDesContraintes(StatutDesContraintes), + UseNamedProblems(UseNamedProblems) { } diff --git a/src/solver/utils/named_problem.h b/src/solver/utils/named_problem.h index 031dea0dad..27050a276f 100644 --- a/src/solver/utils/named_problem.h +++ b/src/solver/utils/named_problem.h @@ -21,17 +21,24 @@ static inline char** VectorOfStringToCharPP(std::vector& in, [](std::string& str) { return str.empty() ? nullptr : str.data(); }); return pointerVec.data(); } +static inline char** CharPP(size_t Size, std::vector& pointerVec) +{ + pointerVec = std::vector(Size, nullptr); + return pointerVec.data(); +} struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE { public: PROBLEME_SIMPLEXE_NOMME(const std::vector& NomDesVariables, const std::vector& NomDesContraintes, std::vector& StatutDesVariables, - std::vector& StatutDesContraintes); + std::vector& StatutDesContraintes, + bool UseNamedProblems); private: std::vector NomDesVariables; std::vector NomDesContraintes; + bool UseNamedProblems; public: std::vector& StatutDesVariables; @@ -39,18 +46,31 @@ struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE bool isMIP() const; bool basisExists() const; + char** VariableNamesAsCharPP(std::vector& pointerVec) { - return VectorOfStringToCharPP(NomDesVariables, pointerVec); + if (UseNamedProblems) + { + return VectorOfStringToCharPP(NomDesVariables, pointerVec); + } + + return CharPP(NomDesVariables.size(), pointerVec); } + char** ConstraintNamesAsCharPP(std::vector& pointerVec) { - return VectorOfStringToCharPP(NomDesContraintes, pointerVec); + if (UseNamedProblems) + { + return VectorOfStringToCharPP(NomDesContraintes, pointerVec); + } + return CharPP(NomDesContraintes.size(), pointerVec); } + const std::vector& VariableNames() const { return NomDesVariables; } + const std::vector& ConstraintNames() const { return NomDesContraintes; From 94cf6e26a79de79b6ed3d0e5504cdccb28dd3e89 Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Tue, 22 Aug 2023 16:14:17 +0200 Subject: [PATCH 07/17] refacto ortools utils --- src/solver/utils/named_problem.cpp | 2 +- src/solver/utils/named_problem.h | 11 +- src/solver/utils/ortools_utils.cpp | 179 ++++++++++++++++++++--------- 3 files changed, 132 insertions(+), 60 deletions(-) diff --git a/src/solver/utils/named_problem.cpp b/src/solver/utils/named_problem.cpp index bf87230306..984e678bc6 100644 --- a/src/solver/utils/named_problem.cpp +++ b/src/solver/utils/named_problem.cpp @@ -17,7 +17,7 @@ PROBLEME_SIMPLEXE_NOMME::PROBLEME_SIMPLEXE_NOMME(const std::vector& NomDesContraintes(NomDesContraintes), StatutDesVariables(StatutDesVariables), StatutDesContraintes(StatutDesContraintes), - UseNamedProblems(UseNamedProblems) + useNamedProblems_(UseNamedProblems) { } diff --git a/src/solver/utils/named_problem.h b/src/solver/utils/named_problem.h index 27050a276f..b826f87ca6 100644 --- a/src/solver/utils/named_problem.h +++ b/src/solver/utils/named_problem.h @@ -38,7 +38,7 @@ struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE private: std::vector NomDesVariables; std::vector NomDesContraintes; - bool UseNamedProblems; + bool useNamedProblems_; public: std::vector& StatutDesVariables; @@ -47,9 +47,14 @@ struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE bool isMIP() const; bool basisExists() const; + bool UseNamedProblems() const + { + return useNamedProblems_; + } + char** VariableNamesAsCharPP(std::vector& pointerVec) { - if (UseNamedProblems) + if (useNamedProblems_) { return VectorOfStringToCharPP(NomDesVariables, pointerVec); } @@ -59,7 +64,7 @@ struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE char** ConstraintNamesAsCharPP(std::vector& pointerVec) { - if (UseNamedProblems) + if (useNamedProblems_) { return VectorOfStringToCharPP(NomDesContraintes, pointerVec); } diff --git a/src/solver/utils/ortools_utils.cpp b/src/solver/utils/ortools_utils.cpp index efb344ccff..94ce2128f6 100644 --- a/src/solver/utils/ortools_utils.cpp +++ b/src/solver/utils/ortools_utils.cpp @@ -9,7 +9,62 @@ using namespace operations_research; const char* const XPRESS_PARAMS = "THREADS 1"; +enum class MATRIX_ELEMENT_TYPE +{ + VARIABLE, + CONSTRAINT +}; + +char FromMatrixElementTypeToChar(MATRIX_ELEMENT_TYPE type) +{ + if (type == MATRIX_ELEMENT_TYPE::VARIABLE) + { + return 'x'; + } + return 'c'; +} +void CheckName(std::string& var_name, unsigned idxVar, MATRIX_ELEMENT_TYPE type) +{ + if (var_name.empty()) + { + var_name = FromMatrixElementTypeToChar(type) + std::to_string(idxVar); + } +} + +static void UpdateCoefficients(MPSolver* solver, + MPObjective* const objective, + const double* bMin, + const double* bMax, + const double* costs, + unsigned idxVar, + std::string& varName, + MATRIX_ELEMENT_TYPE type) +{ + double min_l = 0.0; + if (bMin != NULL) + { + min_l = bMin[idxVar]; + } + double max_l = bMax[idxVar]; + CheckName(varName, idxVar, type); + const MPVariable* var = solver->MakeNumVar(min_l, max_l, varName); + objective->SetCoefficient(var, costs[idxVar]); +} +static void transferVariables(MPSolver* solver, + const double* bMin, + const double* bMax, + const double* costs, + int nbVar) +{ + MPObjective* const objective = solver->MutableObjective(); + for (int idxVar = 0; idxVar < nbVar; ++idxVar) + { + std::string varName; + UpdateCoefficients( + solver, objective, bMin, bMax, costs, idxVar, varName, MATRIX_ELEMENT_TYPE::VARIABLE); + } +} static void transferVariables(MPSolver* solver, const double* bMin, const double* bMax, @@ -20,26 +75,36 @@ static void transferVariables(MPSolver* solver, MPObjective* const objective = solver->MutableObjective(); for (int idxVar = 0; idxVar < nbVar; ++idxVar) { - double min_l = 0.0; - if (bMin != NULL) - { - min_l = bMin[idxVar]; - } - double max_l = bMax[idxVar]; - std::string varName; - if (NomDesVariables[idxVar].empty()) - { - varName = "x" + std::to_string(idxVar); - } - else - { - varName = NomDesVariables[idxVar]; - } - const MPVariable* var = solver->MakeNumVar(min_l, max_l, varName); - objective->SetCoefficient(var, costs[idxVar]); + std::string varName = NomDesVariables[idxVar]; + UpdateCoefficients( + solver, objective, bMin, bMax, costs, idxVar, varName, MATRIX_ELEMENT_TYPE::VARIABLE); } } +static void UpdateContraints(MPSolver* solver, + const double* rhs, + const char* sens, + unsigned idxRow, + std::string& constraintName) +{ + double bMin = -MPSolver::infinity(), bMax = MPSolver::infinity(); + if (sens[idxRow] == '=') + { + bMin = bMax = rhs[idxRow]; + } + else if (sens[idxRow] == '<') + { + bMax = rhs[idxRow]; + } + else if (sens[idxRow] == '>') + { + bMin = rhs[idxRow]; + } + + CheckName(constraintName, idxRow, MATRIX_ELEMENT_TYPE::CONSTRAINT); + + solver->MakeRowConstraint(bMin, bMax, constraintName); +} static void transferRows(MPSolver* solver, const double* rhs, const char* sens, @@ -48,31 +113,16 @@ static void transferRows(MPSolver* solver, { for (int idxRow = 0; idxRow < nbRow; ++idxRow) { - double bMin = -MPSolver::infinity(), bMax = MPSolver::infinity(); - if (sens[idxRow] == '=') - { - bMin = bMax = rhs[idxRow]; - } - else if (sens[idxRow] == '<') - { - bMax = rhs[idxRow]; - } - else if (sens[idxRow] == '>') - { - bMin = rhs[idxRow]; - } - + std::string constraintName = NomDesContraintes[idxRow]; + UpdateContraints(solver, rhs, sens, idxRow, constraintName); + } +} +static void transferRows(MPSolver* solver, const double* rhs, const char* sens, int nbRow) +{ + for (int idxRow = 0; idxRow < nbRow; ++idxRow) + { std::string constraintName; - if (NomDesContraintes[idxRow].empty()) - { - constraintName = "c" + std::to_string(idxRow); - } - else - { - constraintName = NomDesContraintes[idxRow]; - } - - solver->MakeRowConstraint(bMin, bMax, constraintName); + UpdateContraints(solver, rhs, sens, idxRow, constraintName); } } @@ -145,21 +195,38 @@ MPSolver* convert_to_MPSolver( MPSolver* solver = MPSolverFactory(problemeSimplexe, solverName); tuneSolverSpecificOptions(solver); - - // Create the variables and set objective cost. - transferVariables(solver, - problemeSimplexe->Xmin, - problemeSimplexe->Xmax, - problemeSimplexe->CoutLineaire, - problemeSimplexe->NombreDeVariables, - problemeSimplexe->VariableNames()); - - // Create constraints and set coefs - transferRows(solver, - problemeSimplexe->SecondMembre, - problemeSimplexe->Sens, - problemeSimplexe->NombreDeContraintes, - problemeSimplexe->ConstraintNames()); + if (problemeSimplexe->UseNamedProblems()) + { + // Create the variables and set objective cost. + transferVariables(solver, + problemeSimplexe->Xmin, + problemeSimplexe->Xmax, + problemeSimplexe->CoutLineaire, + problemeSimplexe->NombreDeVariables, + problemeSimplexe->VariableNames()); + + // Create constraints and set coefs + transferRows(solver, + problemeSimplexe->SecondMembre, + problemeSimplexe->Sens, + problemeSimplexe->NombreDeContraintes, + problemeSimplexe->ConstraintNames()); + } + else + { + // Create the variables and set objective cost. + transferVariables(solver, + problemeSimplexe->Xmin, + problemeSimplexe->Xmax, + problemeSimplexe->CoutLineaire, + problemeSimplexe->NombreDeVariables); + + // Create constraints and set coefs + transferRows(solver, + problemeSimplexe->SecondMembre, + problemeSimplexe->Sens, + problemeSimplexe->NombreDeContraintes); + } transferMatrix(solver, problemeSimplexe->IndicesDebutDeLigne, problemeSimplexe->NombreDeTermesDesLignes, From ca128505e9c96baa790807e716b6f38bdb8b2110 Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Tue, 22 Aug 2023 16:27:58 +0200 Subject: [PATCH 08/17] enable naming for the analyzer --- src/solver/optimisation/opt_appel_solveur_lineaire.cpp | 1 + src/solver/utils/named_problem.h | 5 +++++ src/solver/utils/ortools_utils.cpp | 5 ++--- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/solver/optimisation/opt_appel_solveur_lineaire.cpp b/src/solver/optimisation/opt_appel_solveur_lineaire.cpp index 1d1b915551..4ee9d58a8a 100644 --- a/src/solver/optimisation/opt_appel_solveur_lineaire.cpp +++ b/src/solver/optimisation/opt_appel_solveur_lineaire.cpp @@ -339,6 +339,7 @@ bool OPT_AppelDuSimplexe(const OptimizationOptions& options, logs.info() << " Solver: Safe resolution failed"; } + Probleme.SetUseNamedProblems(true); Optimization::InfeasibleProblemAnalysis analysis(options.solverName, &Probleme); logs.notice() << " Solver: Starting infeasibility analysis..."; try diff --git a/src/solver/utils/named_problem.h b/src/solver/utils/named_problem.h index b826f87ca6..83e18a39d2 100644 --- a/src/solver/utils/named_problem.h +++ b/src/solver/utils/named_problem.h @@ -52,6 +52,11 @@ struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE return useNamedProblems_; } + void SetUseNamedProblems(bool useNamedProblems) + { + useNamedProblems_ = useNamedProblems; + } + char** VariableNamesAsCharPP(std::vector& pointerVec) { if (useNamedProblems_) diff --git a/src/solver/utils/ortools_utils.cpp b/src/solver/utils/ortools_utils.cpp index 94ce2128f6..13d4ef9604 100644 --- a/src/solver/utils/ortools_utils.cpp +++ b/src/solver/utils/ortools_utils.cpp @@ -187,9 +187,8 @@ namespace Antares { namespace Optimization { -MPSolver* convert_to_MPSolver( - const std::string& solverName, - const PROBLEME_SIMPLEXE_NOMME* problemeSimplexe) +MPSolver* convert_to_MPSolver(const std::string& solverName, + const PROBLEME_SIMPLEXE_NOMME* problemeSimplexe) { // Create the MPSolver MPSolver* solver = MPSolverFactory(problemeSimplexe, solverName); From 049d401865e8f6d6af06525f22a4f69847ec3a6d Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Wed, 23 Aug 2023 17:18:44 +0200 Subject: [PATCH 09/17] format --- src/solver/utils/ortools_utils.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/solver/utils/ortools_utils.cpp b/src/solver/utils/ortools_utils.cpp index 13d4ef9604..618accd043 100644 --- a/src/solver/utils/ortools_utils.cpp +++ b/src/solver/utils/ortools_utils.cpp @@ -51,6 +51,7 @@ static void UpdateCoefficients(MPSolver* solver, const MPVariable* var = solver->MakeNumVar(min_l, max_l, varName); objective->SetCoefficient(var, costs[idxVar]); } + static void transferVariables(MPSolver* solver, const double* bMin, const double* bMax, @@ -65,6 +66,7 @@ static void transferVariables(MPSolver* solver, solver, objective, bMin, bMax, costs, idxVar, varName, MATRIX_ELEMENT_TYPE::VARIABLE); } } + static void transferVariables(MPSolver* solver, const double* bMin, const double* bMax, @@ -105,6 +107,7 @@ static void UpdateContraints(MPSolver* solver, solver->MakeRowConstraint(bMin, bMax, constraintName); } + static void transferRows(MPSolver* solver, const double* rhs, const char* sens, @@ -117,6 +120,7 @@ static void transferRows(MPSolver* solver, UpdateContraints(solver, rhs, sens, idxRow, constraintName); } } + static void transferRows(MPSolver* solver, const double* rhs, const char* sens, int nbRow) { for (int idxRow = 0; idxRow < nbRow; ++idxRow) From 561bccec2c4fb5e0622c0b6144e8ade0010b4aae Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Wed, 23 Aug 2023 17:20:00 +0200 Subject: [PATCH 10/17] format code --- src/solver/utils/named_problem.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/solver/utils/named_problem.h b/src/solver/utils/named_problem.h index 83e18a39d2..e0bcd89cda 100644 --- a/src/solver/utils/named_problem.h +++ b/src/solver/utils/named_problem.h @@ -21,11 +21,13 @@ static inline char** VectorOfStringToCharPP(std::vector& in, [](std::string& str) { return str.empty() ? nullptr : str.data(); }); return pointerVec.data(); } + static inline char** CharPP(size_t Size, std::vector& pointerVec) { pointerVec = std::vector(Size, nullptr); return pointerVec.data(); } + struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE { public: From dba9b4f9ce468c25fff877eb89e05d0fecde20b0 Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Thu, 24 Aug 2023 17:39:53 +0200 Subject: [PATCH 11/17] refactor: Create ProblemSimplexeNommeConverter --- .../infeasible-problem-analysis/problem.cpp | 3 +- src/solver/utils/ortools_utils.cpp | 279 ++++++++---------- src/solver/utils/ortools_utils.h | 49 +++ 3 files changed, 172 insertions(+), 159 deletions(-) diff --git a/src/solver/infeasible-problem-analysis/problem.cpp b/src/solver/infeasible-problem-analysis/problem.cpp index d6ca610f9a..c6d399b568 100644 --- a/src/solver/infeasible-problem-analysis/problem.cpp +++ b/src/solver/infeasible-problem-analysis/problem.cpp @@ -13,7 +13,8 @@ namespace Optimization { InfeasibleProblemAnalysis::InfeasibleProblemAnalysis(const std::string& solverName, const PROBLEME_SIMPLEXE_NOMME* ProbSpx) { - mSolver = std::unique_ptr(convert_to_MPSolver(solverName, ProbSpx)); + mSolver + = std::unique_ptr(ProblemSimplexeNommeConverter(solverName, ProbSpx).Convert()); } void InfeasibleProblemAnalysis::addSlackVariables() diff --git a/src/solver/utils/ortools_utils.cpp b/src/solver/utils/ortools_utils.cpp index c2ba2513cd..87764dd08f 100644 --- a/src/solver/utils/ortools_utils.cpp +++ b/src/solver/utils/ortools_utils.cpp @@ -9,126 +9,6 @@ using namespace operations_research; const char* const XPRESS_PARAMS = "THREADS 1"; -enum class MATRIX_ELEMENT_TYPE -{ - VARIABLE, - CONSTRAINT -}; - -char FromMatrixElementTypeToChar(MATRIX_ELEMENT_TYPE type) -{ - if (type == MATRIX_ELEMENT_TYPE::VARIABLE) - { - return 'x'; - } - return 'c'; -} - -void CheckName(std::string& var_name, unsigned idxVar, MATRIX_ELEMENT_TYPE type) -{ - if (var_name.empty()) - { - var_name = FromMatrixElementTypeToChar(type) + std::to_string(idxVar); - } -} - -static void UpdateCoefficients(MPSolver* solver, - MPObjective* const objective, - const double* bMin, - const double* bMax, - const double* costs, - unsigned idxVar, - std::string& varName, - MATRIX_ELEMENT_TYPE type) -{ - double min_l = 0.0; - if (bMin != NULL) - { - min_l = bMin[idxVar]; - } - double max_l = bMax[idxVar]; - CheckName(varName, idxVar, type); - const MPVariable* var = solver->MakeNumVar(min_l, max_l, varName); - objective->SetCoefficient(var, costs[idxVar]); -} - -static void transferVariables(MPSolver* solver, - const double* bMin, - const double* bMax, - const double* costs, - int nbVar) -{ - MPObjective* const objective = solver->MutableObjective(); - for (int idxVar = 0; idxVar < nbVar; ++idxVar) - { - std::string varName; - UpdateCoefficients( - solver, objective, bMin, bMax, costs, idxVar, varName, MATRIX_ELEMENT_TYPE::VARIABLE); - } -} - -static void transferVariables(MPSolver* solver, - const double* bMin, - const double* bMax, - const double* costs, - int nbVar, - const std::vector& NomDesVariables) -{ - MPObjective* const objective = solver->MutableObjective(); - for (int idxVar = 0; idxVar < nbVar; ++idxVar) - { - std::string varName = NomDesVariables[idxVar]; - UpdateCoefficients( - solver, objective, bMin, bMax, costs, idxVar, varName, MATRIX_ELEMENT_TYPE::VARIABLE); - } -} - -static void UpdateContraints(MPSolver* solver, - const double* rhs, - const char* sens, - unsigned idxRow, - std::string& constraintName) -{ - double bMin = -MPSolver::infinity(), bMax = MPSolver::infinity(); - if (sens[idxRow] == '=') - { - bMin = bMax = rhs[idxRow]; - } - else if (sens[idxRow] == '<') - { - bMax = rhs[idxRow]; - } - else if (sens[idxRow] == '>') - { - bMin = rhs[idxRow]; - } - - CheckName(constraintName, idxRow, MATRIX_ELEMENT_TYPE::CONSTRAINT); - - solver->MakeRowConstraint(bMin, bMax, constraintName); -} - -static void transferRows(MPSolver* solver, - const double* rhs, - const char* sens, - int nbRow, - const std::vector& NomDesContraintes) -{ - for (int idxRow = 0; idxRow < nbRow; ++idxRow) - { - std::string constraintName = NomDesContraintes[idxRow]; - UpdateContraints(solver, rhs, sens, idxRow, constraintName); - } -} - -static void transferRows(MPSolver* solver, const double* rhs, const char* sens, int nbRow) -{ - for (int idxRow = 0; idxRow < nbRow; ++idxRow) - { - std::string constraintName; - UpdateContraints(solver, rhs, sens, idxRow, constraintName); - } -} static void transferMatrix(const MPSolver* solver, const int* indexRows, @@ -191,51 +71,134 @@ namespace Antares { namespace Optimization { -MPSolver* convert_to_MPSolver(const std::string& solverName, - const PROBLEME_SIMPLEXE_NOMME* problemeSimplexe) +ProblemSimplexeNommeConverter::ProblemSimplexeNommeConverter( + const std::string& solverName, + const Antares::Optimization::PROBLEME_SIMPLEXE_NOMME* problemeSimplexe) : + solverName_(solverName), problemeSimplexe_(problemeSimplexe) { - // Create the MPSolver - MPSolver* solver = MPSolverFactory(problemeSimplexe, solverName); + if (problemeSimplexe_->UseNamedProblems()) + { + variableNameManager_.SetTarget(problemeSimplexe_->VariableNames()); + } +} +MPSolver* ProblemSimplexeNommeConverter::Convert() +{ + MPSolver* solver = MPSolverFactory(problemeSimplexe_, solverName_); tuneSolverSpecificOptions(solver); - if (problemeSimplexe->UseNamedProblems()) + + // Create the variables and set objective cost. + CopyVariables(solver); + + // Create constraints and set coefs + CopyRows(solver); + + transferMatrix(solver, + problemeSimplexe_->IndicesDebutDeLigne, + problemeSimplexe_->NombreDeTermesDesLignes, + problemeSimplexe_->IndicesColonnes, + problemeSimplexe_->CoefficientsDeLaMatriceDesContraintes, + problemeSimplexe_->NombreDeContraintes); + + return solver; +} + +void ProblemSimplexeNommeConverter::UpdateCoefficient(unsigned idxVar, + MPSolver* solver, + MPObjective* const objective) +{ + double min_l = 0.0; + if (problemeSimplexe_->Xmin != NULL) { - // Create the variables and set objective cost. - transferVariables(solver, - problemeSimplexe->Xmin, - problemeSimplexe->Xmax, - problemeSimplexe->CoutLineaire, - problemeSimplexe->NombreDeVariables, - problemeSimplexe->VariableNames()); - - // Create constraints and set coefs - transferRows(solver, - problemeSimplexe->SecondMembre, - problemeSimplexe->Sens, - problemeSimplexe->NombreDeContraintes, - problemeSimplexe->ConstraintNames()); + min_l = problemeSimplexe_->Xmin[idxVar]; } - else + double max_l = problemeSimplexe_->Xmax[idxVar]; + const MPVariable* var = solver->MakeNumVar(min_l, max_l, variableNameManager_.GetName(idxVar)); + objective->SetCoefficient(var, problemeSimplexe_->CoutLineaire[idxVar]); +} + +void ProblemSimplexeNommeConverter::CopyVariables(MPSolver* solver) + +{ + MPObjective* const objective = solver->MutableObjective(); + + for (int idxVar = 0; idxVar < problemeSimplexe_->NombreDeVariables; ++idxVar) { - // Create the variables and set objective cost. - transferVariables(solver, - problemeSimplexe->Xmin, - problemeSimplexe->Xmax, - problemeSimplexe->CoutLineaire, - problemeSimplexe->NombreDeVariables); - - // Create constraints and set coefs - transferRows(solver, - problemeSimplexe->SecondMembre, - problemeSimplexe->Sens, - problemeSimplexe->NombreDeContraintes); + UpdateCoefficient(idxVar, solver, objective); } - transferMatrix(solver, - problemeSimplexe->IndicesDebutDeLigne, - problemeSimplexe->NombreDeTermesDesLignes, - problemeSimplexe->IndicesColonnes, - problemeSimplexe->CoefficientsDeLaMatriceDesContraintes, - problemeSimplexe->NombreDeContraintes); +} + +void ProblemSimplexeNommeConverter::UpdateContraints(unsigned idxRow, MPSolver* solver) +{ + double bMin = -MPSolver::infinity(), bMax = MPSolver::infinity(); + if (problemeSimplexe_->Sens[idxRow] == '=') + { + bMin = bMax = problemeSimplexe_->SecondMembre[idxRow]; + } + else if (problemeSimplexe_->Sens[idxRow] == '<') + { + bMax = problemeSimplexe_->SecondMembre[idxRow]; + } + else if (problemeSimplexe_->Sens[idxRow] == '>') + { + bMin = problemeSimplexe_->SecondMembre[idxRow]; + } + + solver->MakeRowConstraint(bMin, bMax, constraintNameManager_.GetName(idxRow)); +} +void ProblemSimplexeNommeConverter::CopyRows(MPSolver* solver) +{ + for (int idxRow = 0; idxRow < problemeSimplexe_->NombreDeContraintes; ++idxRow) + { + UpdateContraints(idxRow, solver); + } +} + +MPSolver* convert_to_MPSolver(const std::string& solverName, + const PROBLEME_SIMPLEXE_NOMME* problemeSimplexe) +{ + // // Create the MPSolver + MPSolver* solver = MPSolverFactory(problemeSimplexe, solverName); + + // tuneSolverSpecificOptions(solver); + // if (problemeSimplexe->UseNamedProblems()) + // { + // // Create the variables and set objective cost. + // transferVariables(solver, + // problemeSimplexe->Xmin, + // problemeSimplexe->Xmax, + // problemeSimplexe->CoutLineaire, + // problemeSimplexe->NombreDeVariables, + // problemeSimplexe->VariableNames()); + + // // Create constraints and set coefs + // transferRows(solver, + // problemeSimplexe->SecondMembre, + // problemeSimplexe->Sens, + // problemeSimplexe->NombreDeContraintes, + // problemeSimplexe->ConstraintNames()); + // } + // else + // { + // // Create the variables and set objective cost. + // transferVariables(solver, + // problemeSimplexe->Xmin, + // problemeSimplexe->Xmax, + // problemeSimplexe->CoutLineaire, + // problemeSimplexe->NombreDeVariables); + + // // Create constraints and set coefs + // transferRows(solver, + // problemeSimplexe->SecondMembre, + // problemeSimplexe->Sens, + // problemeSimplexe->NombreDeContraintes); + // } + // transferMatrix(solver, + // problemeSimplexe->IndicesDebutDeLigne, + // problemeSimplexe->NombreDeTermesDesLignes, + // problemeSimplexe->IndicesColonnes, + // problemeSimplexe->CoefficientsDeLaMatriceDesContraintes, + // problemeSimplexe->NombreDeContraintes); return solver; } diff --git a/src/solver/utils/ortools_utils.h b/src/solver/utils/ortools_utils.h index e3f0987834..727e16b6b6 100644 --- a/src/solver/utils/ortools_utils.h +++ b/src/solver/utils/ortools_utils.h @@ -50,5 +50,54 @@ namespace Optimization MPSolver* convert_to_MPSolver( const std::string& solverName, const Antares::Optimization::PROBLEME_SIMPLEXE_NOMME* problemeSimplexe); + +class Nomenclature +{ +public: + Nomenclature() = delete; + + explicit Nomenclature(char prefix) : prefix_(prefix) + { + } + + void SetTarget(const std::vector& target) + { + target_ = ⌖ + } + + std::string GetName(unsigned index) const + { + if (target_ == nullptr || target_->at(index).empty()) + { + return prefix_ + std::to_string(index); + } + return target_->at(index); + } + +private: + const std::vector* target_ = nullptr; + char prefix_; +}; + +class ProblemSimplexeNommeConverter +{ +public: + explicit ProblemSimplexeNommeConverter( + const std::string& solverName, + const Antares::Optimization::PROBLEME_SIMPLEXE_NOMME* problemeSimplexe); + + MPSolver* Convert(); + +private: + const std::string& solverName_; + const Antares::Optimization::PROBLEME_SIMPLEXE_NOMME* problemeSimplexe_; + Nomenclature variableNameManager_ = Nomenclature('x'); + Nomenclature constraintNameManager_ = Nomenclature('c'); + + void UpdateCoefficient(unsigned idxVar, MPSolver* solver_, MPObjective* const objective_); + void CopyVariables(MPSolver* solver_); + void UpdateContraints(unsigned idxRow, MPSolver* solver_); + void CopyRows(MPSolver* solver_); +}; } } // namespace Antares From 82cbd0e0a86690fb9d955da4ef82c6b9f8f5f2ef Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Fri, 25 Aug 2023 10:51:35 +0200 Subject: [PATCH 12/17] continuing refacto --- src/solver/utils/ortools_utils.cpp | 135 +++++++++-------------------- src/solver/utils/ortools_utils.h | 7 +- 2 files changed, 43 insertions(+), 99 deletions(-) diff --git a/src/solver/utils/ortools_utils.cpp b/src/solver/utils/ortools_utils.cpp index 87764dd08f..35d9a8e05b 100644 --- a/src/solver/utils/ortools_utils.cpp +++ b/src/solver/utils/ortools_utils.cpp @@ -10,28 +10,6 @@ using namespace operations_research; const char* const XPRESS_PARAMS = "THREADS 1"; -static void transferMatrix(const MPSolver* solver, - const int* indexRows, - const int* terms, - const int* indexCols, - const double* coeffs, - int nbRow) -{ - auto variables = solver->variables(); - auto constraints = solver->constraints(); - - for (int idxRow = 0; idxRow < nbRow; ++idxRow) - { - MPConstraint* const ct = constraints[idxRow]; - int debutLigne = indexRows[idxRow]; - for (int idxCoef = 0; idxCoef < terms[idxRow]; ++idxCoef) - { - int pos = debutLigne + idxCoef; - ct->SetCoefficient(variables[indexCols[pos]], coeffs[pos]); - } - } -} - // MPSolverParameters's copy constructor is private static void setGenericParameters(MPSolverParameters& params) { @@ -39,23 +17,6 @@ static void setGenericParameters(MPSolverParameters& params) params.SetIntegerParam(MPSolverParameters::PRESOLVE, 0); } -static void tuneSolverSpecificOptions(MPSolver* solver) -{ - if (!solver) - return; - - switch (solver->ProblemType()) - { - case MPSolver::XPRESS_LINEAR_PROGRAMMING: - case MPSolver::XPRESS_MIXED_INTEGER_PROGRAMMING: - solver->SetSolverSpecificParametersAsString(XPRESS_PARAMS); - break; - // Add solver-specific options here - default: - break; - } -} - static bool solverSupportsWarmStart(const MPSolver::OptimizationProblemType solverType) { switch (solverType) @@ -85,7 +46,7 @@ ProblemSimplexeNommeConverter::ProblemSimplexeNommeConverter( MPSolver* ProblemSimplexeNommeConverter::Convert() { MPSolver* solver = MPSolverFactory(problemeSimplexe_, solverName_); - tuneSolverSpecificOptions(solver); + TuneSolverSpecificOptions(solver); // Create the variables and set objective cost. CopyVariables(solver); @@ -93,16 +54,47 @@ MPSolver* ProblemSimplexeNommeConverter::Convert() // Create constraints and set coefs CopyRows(solver); - transferMatrix(solver, - problemeSimplexe_->IndicesDebutDeLigne, - problemeSimplexe_->NombreDeTermesDesLignes, - problemeSimplexe_->IndicesColonnes, - problemeSimplexe_->CoefficientsDeLaMatriceDesContraintes, - problemeSimplexe_->NombreDeContraintes); + CopyMatrix(solver); return solver; } +void ProblemSimplexeNommeConverter::TuneSolverSpecificOptions(MPSolver* solver) const +{ + if (!solver) + return; + + switch (solver->ProblemType()) + { + case MPSolver::XPRESS_LINEAR_PROGRAMMING: + case MPSolver::XPRESS_MIXED_INTEGER_PROGRAMMING: + solver->SetSolverSpecificParametersAsString(XPRESS_PARAMS); + break; + // Add solver-specific options here + default: + break; + } +} + +void ProblemSimplexeNommeConverter::CopyMatrix(const MPSolver* solver) +{ + auto variables = solver->variables(); + auto constraints = solver->constraints(); + + for (int idxRow = 0; idxRow < problemeSimplexe_->NombreDeContraintes; ++idxRow) + { + MPConstraint* const ct = constraints[idxRow]; + int debutLigne = problemeSimplexe_->IndicesDebutDeLigne[idxRow]; + for (int idxCoef = 0; idxCoef < problemeSimplexe_->NombreDeTermesDesLignes[idxRow]; + ++idxCoef) + { + int pos = debutLigne + idxCoef; + ct->SetCoefficient(variables[problemeSimplexe_->IndicesColonnes[pos]], + problemeSimplexe_->CoefficientsDeLaMatriceDesContraintes[pos]); + } + } +} + void ProblemSimplexeNommeConverter::UpdateCoefficient(unsigned idxVar, MPSolver* solver, MPObjective* const objective) @@ -146,6 +138,7 @@ void ProblemSimplexeNommeConverter::UpdateContraints(unsigned idxRow, MPSolver* solver->MakeRowConstraint(bMin, bMax, constraintNameManager_.GetName(idxRow)); } + void ProblemSimplexeNommeConverter::CopyRows(MPSolver* solver) { for (int idxRow = 0; idxRow < problemeSimplexe_->NombreDeContraintes; ++idxRow) @@ -154,54 +147,6 @@ void ProblemSimplexeNommeConverter::CopyRows(MPSolver* solver) } } -MPSolver* convert_to_MPSolver(const std::string& solverName, - const PROBLEME_SIMPLEXE_NOMME* problemeSimplexe) -{ - // // Create the MPSolver - MPSolver* solver = MPSolverFactory(problemeSimplexe, solverName); - - // tuneSolverSpecificOptions(solver); - // if (problemeSimplexe->UseNamedProblems()) - // { - // // Create the variables and set objective cost. - // transferVariables(solver, - // problemeSimplexe->Xmin, - // problemeSimplexe->Xmax, - // problemeSimplexe->CoutLineaire, - // problemeSimplexe->NombreDeVariables, - // problemeSimplexe->VariableNames()); - - // // Create constraints and set coefs - // transferRows(solver, - // problemeSimplexe->SecondMembre, - // problemeSimplexe->Sens, - // problemeSimplexe->NombreDeContraintes, - // problemeSimplexe->ConstraintNames()); - // } - // else - // { - // // Create the variables and set objective cost. - // transferVariables(solver, - // problemeSimplexe->Xmin, - // problemeSimplexe->Xmax, - // problemeSimplexe->CoutLineaire, - // problemeSimplexe->NombreDeVariables); - - // // Create constraints and set coefs - // transferRows(solver, - // problemeSimplexe->SecondMembre, - // problemeSimplexe->Sens, - // problemeSimplexe->NombreDeContraintes); - // } - // transferMatrix(solver, - // problemeSimplexe->IndicesDebutDeLigne, - // problemeSimplexe->NombreDeTermesDesLignes, - // problemeSimplexe->IndicesColonnes, - // problemeSimplexe->CoefficientsDeLaMatriceDesContraintes, - // problemeSimplexe->NombreDeContraintes); - - return solver; -} } // namespace Optimization } // namespace Antares @@ -296,7 +241,7 @@ MPSolver* ORTOOLS_ConvertIfNeeded(const std::string& solverName, { if (solver == nullptr) { - return Antares::Optimization::convert_to_MPSolver(solverName, Probleme); + return Antares::Optimization::ProblemSimplexeNommeConverter(solverName, Probleme).Convert(); } else { diff --git a/src/solver/utils/ortools_utils.h b/src/solver/utils/ortools_utils.h index 727e16b6b6..4d7b895cad 100644 --- a/src/solver/utils/ortools_utils.h +++ b/src/solver/utils/ortools_utils.h @@ -47,9 +47,6 @@ namespace Antares { namespace Optimization { -MPSolver* convert_to_MPSolver( - const std::string& solverName, - const Antares::Optimization::PROBLEME_SIMPLEXE_NOMME* problemeSimplexe); class Nomenclature { @@ -98,6 +95,8 @@ class ProblemSimplexeNommeConverter void CopyVariables(MPSolver* solver_); void UpdateContraints(unsigned idxRow, MPSolver* solver_); void CopyRows(MPSolver* solver_); + void TuneSolverSpecificOptions(MPSolver* solver) const; + void CopyMatrix(const MPSolver* solver); }; -} +} // namespace Optimization } // namespace Antares From 811fda779ea2ff0b3e0e4e9929f51227beb19a23 Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Fri, 25 Aug 2023 10:59:23 +0200 Subject: [PATCH 13/17] fix missing constaints names --- src/solver/utils/ortools_utils.cpp | 1 + src/solver/utils/ortools_utils.h | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/solver/utils/ortools_utils.cpp b/src/solver/utils/ortools_utils.cpp index 35d9a8e05b..e20c38d84e 100644 --- a/src/solver/utils/ortools_utils.cpp +++ b/src/solver/utils/ortools_utils.cpp @@ -40,6 +40,7 @@ ProblemSimplexeNommeConverter::ProblemSimplexeNommeConverter( if (problemeSimplexe_->UseNamedProblems()) { variableNameManager_.SetTarget(problemeSimplexe_->VariableNames()); + constraintNameManager_.SetTarget(problemeSimplexe_->ConstraintNames()); } } diff --git a/src/solver/utils/ortools_utils.h b/src/solver/utils/ortools_utils.h index 4d7b895cad..3ec59ef13d 100644 --- a/src/solver/utils/ortools_utils.h +++ b/src/solver/utils/ortools_utils.h @@ -91,10 +91,10 @@ class ProblemSimplexeNommeConverter Nomenclature variableNameManager_ = Nomenclature('x'); Nomenclature constraintNameManager_ = Nomenclature('c'); - void UpdateCoefficient(unsigned idxVar, MPSolver* solver_, MPObjective* const objective_); - void CopyVariables(MPSolver* solver_); - void UpdateContraints(unsigned idxRow, MPSolver* solver_); - void CopyRows(MPSolver* solver_); + void UpdateCoefficient(unsigned idxVar, MPSolver* solver, MPObjective* const objective); + void CopyVariables(MPSolver* solver); + void UpdateContraints(unsigned idxRow, MPSolver* solver); + void CopyRows(MPSolver* solver); void TuneSolverSpecificOptions(MPSolver* solver) const; void CopyMatrix(const MPSolver* solver); }; From 61040527e56b85059731c16b2eb5a63190df33d7 Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Fri, 25 Aug 2023 11:48:15 +0200 Subject: [PATCH 14/17] const_cast to avoid unnecessary copy of vector --- src/solver/utils/named_problem.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/solver/utils/named_problem.h b/src/solver/utils/named_problem.h index e0bcd89cda..91501e1911 100644 --- a/src/solver/utils/named_problem.h +++ b/src/solver/utils/named_problem.h @@ -38,8 +38,8 @@ struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE bool UseNamedProblems); private: - std::vector NomDesVariables; - std::vector NomDesContraintes; + const std::vector& NomDesVariables; + const std::vector& NomDesContraintes; bool useNamedProblems_; public: @@ -63,7 +63,8 @@ struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE { if (useNamedProblems_) { - return VectorOfStringToCharPP(NomDesVariables, pointerVec); + return VectorOfStringToCharPP(const_cast&>(NomDesVariables), + pointerVec); } return CharPP(NomDesVariables.size(), pointerVec); @@ -73,7 +74,8 @@ struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE { if (useNamedProblems_) { - return VectorOfStringToCharPP(NomDesContraintes, pointerVec); + return VectorOfStringToCharPP(const_cast&>(NomDesContraintes), + pointerVec); } return CharPP(NomDesContraintes.size(), pointerVec); } From d9a7a70cdef59e4efeac7c83de003383a57878a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 11 Sep 2023 14:57:19 +0200 Subject: [PATCH 15/17] Add interface for problem naming (#1611) * Add interface for problem naming * Add missing header --- src/solver/utils/CMakeLists.txt | 2 ++ src/solver/utils/mps_utils.cpp | 10 +++++--- src/solver/utils/name_translator.cpp | 28 +++++++++++++++++++++ src/solver/utils/name_translator.h | 25 +++++++++++++++++++ src/solver/utils/named_problem.h | 37 ---------------------------- 5 files changed, 61 insertions(+), 41 deletions(-) create mode 100644 src/solver/utils/name_translator.cpp create mode 100644 src/solver/utils/name_translator.h diff --git a/src/solver/utils/CMakeLists.txt b/src/solver/utils/CMakeLists.txt index 5d4bfd160a..aa1a8026f2 100644 --- a/src/solver/utils/CMakeLists.txt +++ b/src/solver/utils/CMakeLists.txt @@ -7,6 +7,8 @@ set(SRC named_problem.cpp mps_utils.h mps_utils.cpp + name_translator.h + name_translator.cpp opt_period_string_generator.h opt_period_string_generator.cpp ) diff --git a/src/solver/utils/mps_utils.cpp b/src/solver/utils/mps_utils.cpp index 0783f74722..cc63f4922b 100644 --- a/src/solver/utils/mps_utils.cpp +++ b/src/solver/utils/mps_utils.cpp @@ -49,6 +49,7 @@ constexpr size_t OPT_APPEL_SOLVEUR_BUFFER_SIZE = 256; #include #include "filename.h" #include "../optimisation/opt_constants.h" +#include "name_translator.h" using namespace Yuni; @@ -57,7 +58,7 @@ using namespace Yuni; class ProblemConverter { public: - void copyProbSimplexeToProbMps(PROBLEME_MPS* dest, PROBLEME_SIMPLEXE_NOMME* src) + void copyProbSimplexeToProbMps(PROBLEME_MPS* dest, PROBLEME_SIMPLEXE_NOMME* src, NameTranslator& nameTranslator) { // Variables dest->NbVar = src->NombreDeVariables; @@ -85,8 +86,8 @@ class ProblemConverter dest->SensDeLaContrainte = src->Sens; // Names - dest->LabelDeLaVariable = src->VariableNamesAsCharPP(mVariableNames); - dest->LabelDeLaContrainte = src->ConstraintNamesAsCharPP(mConstraintNames); + dest->LabelDeLaVariable = nameTranslator.translate(src->VariableNames(), mVariableNames); + dest->LabelDeLaContrainte = nameTranslator.translate(src->ConstraintNames(), mConstraintNames); } private: @@ -105,9 +106,10 @@ void OPT_EcrireJeuDeDonneesLineaireAuFormatMPS(PROBLEME_SIMPLEXE_NOMME* Prob, auto mps = std::make_shared(); { + auto translator = NameTranslator::create(Prob->UseNamedProblems()); ProblemConverter converter; // This object must not be destroyed until SRSwritempsprob has been run - converter.copyProbSimplexeToProbMps(mps.get(), Prob); + converter.copyProbSimplexeToProbMps(mps.get(), Prob, *translator); SRSwritempsprob(mps.get(), tmpPath.c_str()); } diff --git a/src/solver/utils/name_translator.cpp b/src/solver/utils/name_translator.cpp new file mode 100644 index 0000000000..6c3374fee1 --- /dev/null +++ b/src/solver/utils/name_translator.cpp @@ -0,0 +1,28 @@ +#include "name_translator.h" +#include +#include + +char** RealName::translate(const std::vector& src, + std::vector& pointerVec) +{ + std::transform(src.begin(), + src.end(), + std::back_inserter(pointerVec), + [](const std::string& str) { return str.empty() ? nullptr : const_cast(str.data()); }); + return pointerVec.data(); +} + +char** NullName::translate(const std::vector& src, + std::vector& pointerVec) +{ + pointerVec.assign(src.size(), nullptr); + return pointerVec.data(); +} + +std::unique_ptr NameTranslator::create(bool useRealNames) +{ + if (useRealNames) + return std::make_unique(); + else + return std::make_unique(); +} diff --git a/src/solver/utils/name_translator.h b/src/solver/utils/name_translator.h new file mode 100644 index 0000000000..a179bf1caf --- /dev/null +++ b/src/solver/utils/name_translator.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include + +class NameTranslator +{ +public: + virtual char** translate(const std::vector& src, + std::vector& pointerVec) = 0; + static std::unique_ptr create(bool useRealNames); +}; + +class RealName : public NameTranslator +{ + char** translate(const std::vector& src, + std::vector& pointerVec) override; +}; + +class NullName : public NameTranslator +{ + char** translate(const std::vector& src, + std::vector& pointerVec) override; +}; diff --git a/src/solver/utils/named_problem.h b/src/solver/utils/named_problem.h index 91501e1911..7e749e29ee 100644 --- a/src/solver/utils/named_problem.h +++ b/src/solver/utils/named_problem.h @@ -12,22 +12,6 @@ namespace Antares { namespace Optimization { -static inline char** VectorOfStringToCharPP(std::vector& in, - std::vector& pointerVec) -{ - std::transform(in.begin(), - in.end(), - std::back_inserter(pointerVec), - [](std::string& str) { return str.empty() ? nullptr : str.data(); }); - return pointerVec.data(); -} - -static inline char** CharPP(size_t Size, std::vector& pointerVec) -{ - pointerVec = std::vector(Size, nullptr); - return pointerVec.data(); -} - struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE { public: @@ -59,27 +43,6 @@ struct PROBLEME_SIMPLEXE_NOMME : public PROBLEME_SIMPLEXE useNamedProblems_ = useNamedProblems; } - char** VariableNamesAsCharPP(std::vector& pointerVec) - { - if (useNamedProblems_) - { - return VectorOfStringToCharPP(const_cast&>(NomDesVariables), - pointerVec); - } - - return CharPP(NomDesVariables.size(), pointerVec); - } - - char** ConstraintNamesAsCharPP(std::vector& pointerVec) - { - if (useNamedProblems_) - { - return VectorOfStringToCharPP(const_cast&>(NomDesContraintes), - pointerVec); - } - return CharPP(NomDesContraintes.size(), pointerVec); - } - const std::vector& VariableNames() const { return NomDesVariables; From 6ab7498ee0ba716e1cd3b3f3ce2a70d5b27dccf8 Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Wed, 13 Sep 2023 12:35:44 +0200 Subject: [PATCH 16/17] secure --- .../constraint.cpp | 51 ++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/src/solver/infeasible-problem-analysis/constraint.cpp b/src/solver/infeasible-problem-analysis/constraint.cpp index 1e0204d8a3..557bb516af 100644 --- a/src/solver/infeasible-problem-analysis/constraint.cpp +++ b/src/solver/infeasible-problem-analysis/constraint.cpp @@ -2,6 +2,8 @@ #include "constraint.h" #include +#include +#include namespace Antares { @@ -39,20 +41,45 @@ double Constraint::getSlackValue() const { return mSlackValue; } -std::vector split(const std::string& s, char delimiter) + +class StringIsNotWellFormated : public std::runtime_error { - std::vector tokens; - std::string token; - std::istringstream tokenStream(s); - while (std::getline(tokenStream, token, delimiter)) - { - tokens.push_back(token); - } - return tokens; -} +public: + StringIsNotWellFormated(const std::string& error_message) : std::runtime_error(error_message) + { + } +}; -std::string StringBetweenAngleBrackets(const std::string& str){ - return split(split(str, '<')[1], '>')[0]; +std::string StringBetweenAngleBrackets(const std::string& str) +{ + const auto& str_begin_iterator = str.begin(); + const auto& str_end_iterator = str.end(); + auto left = std::find(str.begin(), str.end(), '<'); + if (left == str_end_iterator) + { + std::ostringstream stream; + stream << std::string("Error the string: ") << std::quoted(str) + << " does not contains the left angle bracket " << std::quoted("<"); + throw StringIsNotWellFormated(stream.str()); + } + + auto right = std::find(str_begin_iterator, str_end_iterator, '>'); + if (right == str_end_iterator) + { + std::ostringstream stream; + stream << std::string("Error the string: ") << std::quoted(str) + << " does not contains the right angle bracket " << std::quoted(">"); + throw StringIsNotWellFormated(stream.str()); + } + + if (std::distance(left, right) <= 1) + { + std::ostringstream stream; + stream << std::string("Error the string: ") << std::quoted(str) << " must be of format " + << std::quoted("**"); + throw StringIsNotWellFormated(stream.str()); + } + return std::string(left + 1, right); } std::string Constraint::getAreaName() const From e7bc16779fd29c64a2e68e5108b0788e598ed369 Mon Sep 17 00:00:00 2001 From: Abdoulbari ZAKIR Date: Wed, 13 Sep 2023 14:33:31 +0200 Subject: [PATCH 17/17] tiny --- .../infeasible-problem-analysis/constraint.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/solver/infeasible-problem-analysis/constraint.cpp b/src/solver/infeasible-problem-analysis/constraint.cpp index 557bb516af..ba8788ebcc 100644 --- a/src/solver/infeasible-problem-analysis/constraint.cpp +++ b/src/solver/infeasible-problem-analysis/constraint.cpp @@ -52,10 +52,12 @@ class StringIsNotWellFormated : public std::runtime_error std::string StringBetweenAngleBrackets(const std::string& str) { - const auto& str_begin_iterator = str.begin(); - const auto& str_end_iterator = str.end(); - auto left = std::find(str.begin(), str.end(), '<'); - if (left == str_end_iterator) + const auto& begin = str.begin(); + const auto& end = str.end(); + + auto left = std::find(begin, end, '<'); + + if (left == end) { std::ostringstream stream; stream << std::string("Error the string: ") << std::quoted(str) @@ -63,8 +65,8 @@ std::string StringBetweenAngleBrackets(const std::string& str) throw StringIsNotWellFormated(stream.str()); } - auto right = std::find(str_begin_iterator, str_end_iterator, '>'); - if (right == str_end_iterator) + auto right = std::find(begin, end, '>'); + if (right == end) { std::ostringstream stream; stream << std::string("Error the string: ") << std::quoted(str)