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/api/include/antares/solver/modeler/api/linearProblem.h b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h index 6885d81ac1..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,6 +72,8 @@ class ILinearProblem /// Solve the problem, returns a IMipSolution virtual IMipSolution* solve(bool verboseSolver) = 0; + virtual void WriteLP(const std::string& filename) = 0; + // Definition of infinity virtual double infinity() const = 0; }; 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..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 @@ -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& getOptimalValues() const = 0; }; } // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/main.cpp b/src/solver/modeler/main.cpp index a4d071660b..08ca33d2a0 100644 --- a/src/solver/modeler/main.cpp +++ b/src/solver/modeler/main.cpp @@ -19,9 +19,14 @@ * along with Antares_Simulator. If not, see . */ +#include + #include +#include #include +#include #include +#include using namespace Antares; using namespace Antares::Solver; @@ -51,6 +56,57 @@ 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}; + // 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 = 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); + for (auto& filler: fillers) + { + delete filler; + } + + logs.info() << "Number of variables: " << pb.variableCount(); + logs.info() << "Number of constraints: " << pb.constraintCount(); + + if (!parameters.noOutput) + { + logs.info() << "Writing problem.lp..."; + auto mps_path = std::filesystem::current_path() / "problem.lp"; + pb.WriteLP(mps_path.string()); + } + + 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->getOptimalValues()) + { + 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/linearProblem.h b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h index 3d69ee98e9..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,6 +65,7 @@ class OrtoolsLinearProblem: public Api::ILinearProblem bool isMaximization() const override; OrtoolsMipSolution* solve(bool verboseSolver) override; + void WriteLP(const std::string& filename) override; double infinity() const override; 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..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,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& getOptimalValues() const override; private: operations_research::MPSolver::ResultStatus status_; diff --git a/src/solver/modeler/ortoolsImpl/linearProblem.cpp b/src/solver/modeler/ortoolsImpl/linearProblem.cpp index feba47dda8..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,6 +166,14 @@ bool OrtoolsLinearProblem::isMaximization() const return objective_->maximization(); } +void OrtoolsLinearProblem::WriteLP(const std::string& filename) +{ + std::string out; + mpSolver_->ExportModelAsLpFormat(false, &out); + std::ofstream of(filename); + of << out; +} + MPSolver* OrtoolsLinearProblem::MpSolver() const { return mpSolver_; diff --git a/src/solver/modeler/ortoolsImpl/mipSolution.cpp b/src/solver/modeler/ortoolsImpl/mipSolution.cpp index 8239f9893a..b10386a1a4 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::getOptimalValues() const +{ + return solution_; +} + } // namespace Antares::Solver::Modeler::OrtoolsImpl