From 69a5225dafdd68c24591f22a09c48a03193f037c Mon Sep 17 00:00:00 2001 From: Florian OMNES Date: Tue, 7 Jan 2025 14:13:49 +0100 Subject: [PATCH 1/9] 2.5b build linear problem from components --- src/solver/modeler/CMakeLists.txt | 4 ++++ src/solver/modeler/main.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/solver/modeler/CMakeLists.txt b/src/solver/modeler/CMakeLists.txt index cb31b11fd4..da059fbe1f 100644 --- a/src/solver/modeler/CMakeLists.txt +++ b/src/solver/modeler/CMakeLists.txt @@ -22,6 +22,10 @@ target_link_libraries(modeler-lib INTERFACE Antares::loadModelerFiles Antares::modelerParameters + Antares::optim-model-filler + Antares::modeler_api + # TODO FIXME don't depend on implementations + Antares::modeler-ortools-impl ) target_link_libraries(antares-modeler diff --git a/src/solver/modeler/main.cpp b/src/solver/modeler/main.cpp index a4d071660b..4f687a98b9 100644 --- a/src/solver/modeler/main.cpp +++ b/src/solver/modeler/main.cpp @@ -20,8 +20,11 @@ */ #include +#include #include +#include #include +#include using namespace Antares; using namespace Antares::Solver; @@ -51,6 +54,27 @@ int main(int argc, const char** argv) logs.info() << "Libraries loaded"; const auto system = LoadFiles::loadSystem(studyPath, libraries); logs.info() << "System loaded"; + + // Fillers, etc. + std::vector fillers; + // TODO memory + for (auto& [_, component]: system.Components()) + { + fillers.push_back(new Antares::Optimization::ComponentFiller(component)); + } + + Antares::Solver::Modeler::Api::LinearProblemData LP_Data; + Antares::Solver::Modeler::Api::FillContext ctx = {0, 0}; + Antares::Solver::Modeler::OrtoolsImpl::OrtoolsLinearProblem pb(false, parameters.solver); + Antares::Solver::Modeler::Api::LinearProblemBuilder linear_problem_builder(fillers); + linear_problem_builder.build(pb, LP_Data, ctx); + for (auto& filler: fillers) + { + delete filler; + } + + logs.info() << "Number of variables: " << pb.variableCount(); + logs.info() << "Number of constraints: " << pb.constraintCount(); } catch (const LoadFiles::ErrorLoadingYaml&) { From 306d8f3d05805ce9b503beaad3ac205fed1d9be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Wed, 8 Jan 2025 16:08:25 +0100 Subject: [PATCH 2/9] Print solution values in the logs if a solution exists (#2562) Co-authored-by: Vincent Payet --- .../antares/solver/modeler/api/mipSolution.h | 3 +++ src/solver/modeler/main.cpp | 22 +++++++++++++++++++ .../solver/modeler/ortoolsImpl/mipSolution.h | 1 + .../modeler/ortoolsImpl/mipSolution.cpp | 5 +++++ 4 files changed, 31 insertions(+) diff --git a/src/solver/modeler/api/include/antares/solver/modeler/api/mipSolution.h b/src/solver/modeler/api/include/antares/solver/modeler/api/mipSolution.h index 0018718de2..9311064e30 100644 --- a/src/solver/modeler/api/include/antares/solver/modeler/api/mipSolution.h +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/mipSolution.h @@ -21,6 +21,8 @@ #pragma once +#include +#include #include #include "mipVariable.h" @@ -51,6 +53,7 @@ class IMipSolution virtual double getObjectiveValue() const = 0; virtual double getOptimalValue(const IMipVariable* var) const = 0; virtual std::vector getOptimalValues(const std::vector& vars) const = 0; + virtual const std::map& solutionValues() const = 0; }; } // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/main.cpp b/src/solver/modeler/main.cpp index 4f687a98b9..141b4986bf 100644 --- a/src/solver/modeler/main.cpp +++ b/src/solver/modeler/main.cpp @@ -19,6 +19,8 @@ * along with Antares_Simulator. If not, see . */ +#include + #include #include #include @@ -75,6 +77,26 @@ int main(int argc, const char** argv) logs.info() << "Number of variables: " << pb.variableCount(); logs.info() << "Number of constraints: " << pb.constraintCount(); + + logs.info() << "Launching resolution..."; + auto* solution = pb.solve(parameters.solverLogs); + switch (solution->getStatus()) + { + case Antares::Solver::Modeler::Api::MipStatus::OPTIMAL: + case Antares::Solver::Modeler::Api::MipStatus::FEASIBLE: + if (!parameters.noOutput) + { + logs.info() << "Writing variables..."; + std::ofstream sol_out(std::filesystem::current_path() / "solution.csv"); + for (const auto& [name, value]: solution->solutionValues()) + { + sol_out << name << " " << value << std::endl; + } + } + break; + default: + logs.error() << "Problem during linear optimization"; + } } catch (const LoadFiles::ErrorLoadingYaml&) { diff --git a/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipSolution.h b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipSolution.h index 0cf452c11b..96adb8fa2b 100644 --- a/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipSolution.h +++ b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipSolution.h @@ -44,6 +44,7 @@ class OrtoolsMipSolution final: public Api::IMipSolution double getOptimalValue(const Api::IMipVariable* var) const override; std::vector getOptimalValues( const std::vector& vars) const override; + const std::map& solutionValues() const override; private: operations_research::MPSolver::ResultStatus status_; diff --git a/src/solver/modeler/ortoolsImpl/mipSolution.cpp b/src/solver/modeler/ortoolsImpl/mipSolution.cpp index 8239f9893a..7fd68c886f 100644 --- a/src/solver/modeler/ortoolsImpl/mipSolution.cpp +++ b/src/solver/modeler/ortoolsImpl/mipSolution.cpp @@ -93,4 +93,9 @@ std::vector OrtoolsMipSolution::getOptimalValues( return solution; } +const std::map& OrtoolsMipSolution::solutionValues() const +{ + return solution_; +} + } // namespace Antares::Solver::Modeler::OrtoolsImpl From 59f68afedf0ef8bd98f9e27704e00267c30a7970 Mon Sep 17 00:00:00 2001 From: Florian OMNES Date: Wed, 8 Jan 2025 16:30:59 +0100 Subject: [PATCH 3/9] write mps --- src/solver/modeler/main.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/solver/modeler/main.cpp b/src/solver/modeler/main.cpp index 141b4986bf..85a12d3d10 100644 --- a/src/solver/modeler/main.cpp +++ b/src/solver/modeler/main.cpp @@ -78,6 +78,13 @@ int main(int argc, const char** argv) logs.info() << "Number of variables: " << pb.variableCount(); logs.info() << "Number of constraints: " << pb.constraintCount(); + if (!parameters.noOutput) + { + logs.info() << "Writing problem.mps..."; + auto mps_path = std::filesystem::current_path() / "problem.mps"; + pb.MpSolver()->Write(mps_path.c_str()); + } + logs.info() << "Launching resolution..."; auto* solution = pb.solve(parameters.solverLogs); switch (solution->getStatus()) From 4a72ccae8f1a271fa163b53bbc47a7779c72e021 Mon Sep 17 00:00:00 2001 From: Florian OMNES Date: Wed, 8 Jan 2025 16:32:10 +0100 Subject: [PATCH 4/9] Force MIP --- src/solver/modeler/main.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/solver/modeler/main.cpp b/src/solver/modeler/main.cpp index 85a12d3d10..b51b8c78bf 100644 --- a/src/solver/modeler/main.cpp +++ b/src/solver/modeler/main.cpp @@ -67,7 +67,10 @@ int main(int argc, const char** argv) Antares::Solver::Modeler::Api::LinearProblemData LP_Data; Antares::Solver::Modeler::Api::FillContext ctx = {0, 0}; - Antares::Solver::Modeler::OrtoolsImpl::OrtoolsLinearProblem pb(false, parameters.solver); + // We force the usage of MIP solvers to check that integer variables are properly handled + // TODO determine the nature of the problem based on system.Components() + const bool isMip = false; + Antares::Solver::Modeler::OrtoolsImpl::OrtoolsLinearProblem pb(isMip, parameters.solver); Antares::Solver::Modeler::Api::LinearProblemBuilder linear_problem_builder(fillers); linear_problem_builder.build(pb, LP_Data, ctx); for (auto& filler: fillers) From 7edc1a0b9d3aa9fa55029eadb67fdd818ae651cb Mon Sep 17 00:00:00 2001 From: Florian OMNES Date: Wed, 8 Jan 2025 16:34:08 +0100 Subject: [PATCH 5/9] fix --- src/solver/modeler/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solver/modeler/main.cpp b/src/solver/modeler/main.cpp index b51b8c78bf..5e75b34a2d 100644 --- a/src/solver/modeler/main.cpp +++ b/src/solver/modeler/main.cpp @@ -69,7 +69,7 @@ int main(int argc, const char** argv) Antares::Solver::Modeler::Api::FillContext ctx = {0, 0}; // We force the usage of MIP solvers to check that integer variables are properly handled // TODO determine the nature of the problem based on system.Components() - const bool isMip = false; + const bool isMip = true; Antares::Solver::Modeler::OrtoolsImpl::OrtoolsLinearProblem pb(isMip, parameters.solver); Antares::Solver::Modeler::Api::LinearProblemBuilder linear_problem_builder(fillers); linear_problem_builder.build(pb, LP_Data, ctx); From ba6a21206f3f579d62db1f219d1691b458da8346 Mon Sep 17 00:00:00 2001 From: Florian OMNES Date: Wed, 8 Jan 2025 16:52:20 +0100 Subject: [PATCH 6/9] Expose method Write instead of relying on protected MpSolver method --- .../api/include/antares/solver/modeler/api/linearProblem.h | 2 ++ src/solver/modeler/main.cpp | 2 +- .../antares/solver/modeler/ortoolsImpl/linearProblem.h | 1 + src/solver/modeler/ortoolsImpl/linearProblem.cpp | 5 +++++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h index 6885d81ac1..17cd8c6f8b 100644 --- a/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h @@ -72,6 +72,8 @@ class ILinearProblem /// Solve the problem, returns a IMipSolution virtual IMipSolution* solve(bool verboseSolver) = 0; + virtual void Write(const std::string& filename) = 0; + // Definition of infinity virtual double infinity() const = 0; }; diff --git a/src/solver/modeler/main.cpp b/src/solver/modeler/main.cpp index 5e75b34a2d..837eabb08a 100644 --- a/src/solver/modeler/main.cpp +++ b/src/solver/modeler/main.cpp @@ -85,7 +85,7 @@ int main(int argc, const char** argv) { logs.info() << "Writing problem.mps..."; auto mps_path = std::filesystem::current_path() / "problem.mps"; - pb.MpSolver()->Write(mps_path.c_str()); + pb.Write(mps_path.c_str()); } logs.info() << "Launching resolution..."; diff --git a/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h index 3d69ee98e9..4cf5b72e90 100644 --- a/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h +++ b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h @@ -65,6 +65,7 @@ class OrtoolsLinearProblem: public Api::ILinearProblem bool isMaximization() const override; OrtoolsMipSolution* solve(bool verboseSolver) override; + void Write(const std::string& filename) override; double infinity() const override; diff --git a/src/solver/modeler/ortoolsImpl/linearProblem.cpp b/src/solver/modeler/ortoolsImpl/linearProblem.cpp index feba47dda8..df07989c29 100644 --- a/src/solver/modeler/ortoolsImpl/linearProblem.cpp +++ b/src/solver/modeler/ortoolsImpl/linearProblem.cpp @@ -165,6 +165,11 @@ bool OrtoolsLinearProblem::isMaximization() const return objective_->maximization(); } +void OrtoolsLinearProblem::Write(const std::string& filename) +{ + mpSolver_->Write(filename); +} + MPSolver* OrtoolsLinearProblem::MpSolver() const { return mpSolver_; From eb4dd66d46cd33abbf2d8c8f81ce46310ba648b6 Mon Sep 17 00:00:00 2001 From: Florian OMNES Date: Wed, 8 Jan 2025 17:32:48 +0100 Subject: [PATCH 7/9] Rename --- .../api/include/antares/solver/modeler/api/mipSolution.h | 2 +- src/solver/modeler/main.cpp | 2 +- .../include/antares/solver/modeler/ortoolsImpl/mipSolution.h | 2 +- src/solver/modeler/ortoolsImpl/mipSolution.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/solver/modeler/api/include/antares/solver/modeler/api/mipSolution.h b/src/solver/modeler/api/include/antares/solver/modeler/api/mipSolution.h index 9311064e30..4a8b7237dc 100644 --- a/src/solver/modeler/api/include/antares/solver/modeler/api/mipSolution.h +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/mipSolution.h @@ -53,7 +53,7 @@ class IMipSolution virtual double getObjectiveValue() const = 0; virtual double getOptimalValue(const IMipVariable* var) const = 0; virtual std::vector getOptimalValues(const std::vector& vars) const = 0; - virtual const std::map& solutionValues() const = 0; + virtual const std::map& getOptimalValues() const = 0; }; } // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/main.cpp b/src/solver/modeler/main.cpp index 837eabb08a..4b52470f83 100644 --- a/src/solver/modeler/main.cpp +++ b/src/solver/modeler/main.cpp @@ -98,7 +98,7 @@ int main(int argc, const char** argv) { logs.info() << "Writing variables..."; std::ofstream sol_out(std::filesystem::current_path() / "solution.csv"); - for (const auto& [name, value]: solution->solutionValues()) + for (const auto& [name, value]: solution->getOptimalValues()) { sol_out << name << " " << value << std::endl; } diff --git a/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipSolution.h b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipSolution.h index 96adb8fa2b..f536329e36 100644 --- a/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipSolution.h +++ b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipSolution.h @@ -44,7 +44,7 @@ class OrtoolsMipSolution final: public Api::IMipSolution double getOptimalValue(const Api::IMipVariable* var) const override; std::vector getOptimalValues( const std::vector& vars) const override; - const std::map& solutionValues() const override; + const std::map& getOptimalValues() const override; private: operations_research::MPSolver::ResultStatus status_; diff --git a/src/solver/modeler/ortoolsImpl/mipSolution.cpp b/src/solver/modeler/ortoolsImpl/mipSolution.cpp index 7fd68c886f..b10386a1a4 100644 --- a/src/solver/modeler/ortoolsImpl/mipSolution.cpp +++ b/src/solver/modeler/ortoolsImpl/mipSolution.cpp @@ -93,7 +93,7 @@ std::vector OrtoolsMipSolution::getOptimalValues( return solution; } -const std::map& OrtoolsMipSolution::solutionValues() const +const std::map& OrtoolsMipSolution::getOptimalValues() const { return solution_; } From 970297cda79c7ad6de634140df68214829dd8430 Mon Sep 17 00:00:00 2001 From: Florian OMNES Date: Thu, 9 Jan 2025 15:20:56 +0100 Subject: [PATCH 8/9] Use WriteLP --- .../include/antares/solver/modeler/api/linearProblem.h | 2 +- src/solver/modeler/main.cpp | 6 +++--- .../antares/solver/modeler/ortoolsImpl/linearProblem.h | 2 +- src/solver/modeler/ortoolsImpl/linearProblem.cpp | 8 ++++++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h index 17cd8c6f8b..dffc7f874c 100644 --- a/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h @@ -72,7 +72,7 @@ class ILinearProblem /// Solve the problem, returns a IMipSolution virtual IMipSolution* solve(bool verboseSolver) = 0; - virtual void Write(const std::string& filename) = 0; + virtual void WriteLP(const std::string& filename) = 0; // Definition of infinity virtual double infinity() const = 0; diff --git a/src/solver/modeler/main.cpp b/src/solver/modeler/main.cpp index 4b52470f83..43bfc19593 100644 --- a/src/solver/modeler/main.cpp +++ b/src/solver/modeler/main.cpp @@ -83,9 +83,9 @@ int main(int argc, const char** argv) if (!parameters.noOutput) { - logs.info() << "Writing problem.mps..."; - auto mps_path = std::filesystem::current_path() / "problem.mps"; - pb.Write(mps_path.c_str()); + logs.info() << "Writing problem.lp..."; + auto mps_path = std::filesystem::current_path() / "problem.lp"; + pb.WriteLP(mps_path.c_str()); } logs.info() << "Launching resolution..."; diff --git a/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h index 4cf5b72e90..f4a2fed61e 100644 --- a/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h +++ b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h @@ -65,7 +65,7 @@ class OrtoolsLinearProblem: public Api::ILinearProblem bool isMaximization() const override; OrtoolsMipSolution* solve(bool verboseSolver) override; - void Write(const std::string& filename) override; + void WriteLP(const std::string& filename) override; double infinity() const override; diff --git a/src/solver/modeler/ortoolsImpl/linearProblem.cpp b/src/solver/modeler/ortoolsImpl/linearProblem.cpp index df07989c29..20c302c9fd 100644 --- a/src/solver/modeler/ortoolsImpl/linearProblem.cpp +++ b/src/solver/modeler/ortoolsImpl/linearProblem.cpp @@ -20,6 +20,7 @@ */ #include +#include #include #include @@ -165,9 +166,12 @@ bool OrtoolsLinearProblem::isMaximization() const return objective_->maximization(); } -void OrtoolsLinearProblem::Write(const std::string& filename) +void OrtoolsLinearProblem::WriteLP(const std::string& filename) { - mpSolver_->Write(filename); + std::string out; + mpSolver_->ExportModelAsLpFormat(false, &out); + std::ofstream of(filename); + of << out; } MPSolver* OrtoolsLinearProblem::MpSolver() const From fa9bf5451d9513e8aff5e3f0866776c014d03f86 Mon Sep 17 00:00:00 2001 From: Florian OMNES Date: Thu, 9 Jan 2025 17:05:39 +0100 Subject: [PATCH 9/9] MSVC is so strict with types ! --- src/solver/modeler/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solver/modeler/main.cpp b/src/solver/modeler/main.cpp index 43bfc19593..08ca33d2a0 100644 --- a/src/solver/modeler/main.cpp +++ b/src/solver/modeler/main.cpp @@ -85,7 +85,7 @@ int main(int argc, const char** argv) { logs.info() << "Writing problem.lp..."; auto mps_path = std::filesystem::current_path() / "problem.lp"; - pb.WriteLP(mps_path.c_str()); + pb.WriteLP(mps_path.string()); } logs.info() << "Launching resolution...";