From 66e8b83ee454c1a00bc0fabc9777a2d3c0f18ef7 Mon Sep 17 00:00:00 2001 From: Henri Lefebvre Date: Thu, 24 Oct 2024 15:01:18 +0200 Subject: [PATCH] remove AbstractSolution and Solution:: --- lib/CMakeLists.txt | 3 +- lib/include/idol/containers/GeneratorPool.h | 4 +- .../idol/modeling/constraints/TempCtr.h | 2 +- .../idol/modeling/expressions/AbstractExpr.h | 4 +- .../idol/modeling/expressions/Constant.h | 5 +- lib/include/idol/modeling/expressions/Expr.h | 6 +- .../idol/modeling/expressions/LinExpr.h | 4 +- .../expressions/operations/operators.h | 2 +- lib/include/idol/modeling/matrix/Row.h | 4 +- lib/include/idol/modeling/models/Model.h | 10 +- .../modeling/solutions/AbstractSolution.h | 338 ------------------ lib/include/idol/modeling/solutions/Point.h | 71 ++++ .../idol/modeling/solutions/Solution.h | 87 ----- .../modeling/sparse-matrix/SparseVector.h | 69 +++- lib/include/idol/optimizers/Algorithm.h | 2 +- .../wrappers/MibS/MibSCallbackI.h | 12 +- .../impls/BranchingWithPriority.h | 2 +- .../branching-rules/impls/VariableBranching.h | 4 +- .../AbstractBranchAndBoundCallbackI.h | 2 +- .../CallbackAsBranchAndBoundCallback.h | 4 +- .../branch-and-bound/logs/Info.h | 1 + .../branch-and-bound/nodes/DefaultNodeInfo.h | 4 +- .../callbacks/Callback.h | 10 +- .../callbacks/cutting-planes/CutSeparation.h | 2 +- .../dantzig-wolfe/ColumnGeneration.h | 6 +- .../dantzig-wolfe/Formulation.h | 14 +- .../ArtificialCosts.h | 4 +- .../DantzigWolfeInfeasibilityStrategy.h | 8 +- .../DualPriceSmoothingStabilization.h | 6 +- .../dantzig-wolfe/stabilization/Neame.h | 6 +- .../stabilization/NoStabilization.h | 4 +- .../dantzig-wolfe/stabilization/Wentges.h | 6 +- .../padm/Formulation.h | 8 +- .../padm/Optimizers_PADM.h | 6 +- .../padm/SubProblem.h | 8 +- .../wrappers/GLPK/Optimizers_GLPK.h | 4 +- .../wrappers/Gurobi/GurobiCallbackI.h | 4 +- .../wrappers/Mosek/MosekCallbackI.h | 4 +- lib/src/modeling/constraints/TempCtr.cpp | 4 +- lib/src/modeling/expressions/Constant.cpp | 6 +- .../expressions/operations/operators.cpp | 4 +- lib/src/modeling/matrix/Row.cpp | 6 +- .../callbacks/Callback.cpp | 4 +- .../callbacks/CutSeparation.cpp | 2 +- .../dantzig-wolfe/Formulation.cpp | 20 +- .../ArtificialCosts.cpp | 6 +- .../DantzigWolfeInfeasibilityStrategy.cpp | 2 +- .../padm/Formulation.cpp | 8 +- .../padm/Optimizers_PADM.cpp | 9 +- .../padm/SubProblem.cpp | 6 +- .../wrappers/GLPK/Optimizers_GLPK.cpp | 4 +- .../wrappers/Gurobi/GurobiCallbackI.cpp | 6 +- .../wrappers/Mosek/MosekCallbackI.cpp | 4 +- 53 files changed, 264 insertions(+), 567 deletions(-) delete mode 100644 lib/include/idol/modeling/solutions/AbstractSolution.h create mode 100644 lib/include/idol/modeling/solutions/Point.h delete mode 100644 lib/include/idol/modeling/solutions/Solution.h diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index bc19cd0c..9fc44f63 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -15,8 +15,6 @@ add_library(idol STATIC include/idol/modeling/constraints/TempCtr.h src/modeling/constraints/TempCtr.cpp include/idol/containers/IteratorForward.h - include/idol/modeling/solutions/AbstractSolution.h - include/idol/modeling/solutions/Solution.h include/idol/modeling/variables/TempVar.h include/idol/containers/Set.h include/idol/errors/NotImplemented.h @@ -241,6 +239,7 @@ add_library(idol STATIC src/optimizers/mixed-integer-optimization/callbacks/watchers/Plots_OptimalityGap.cpp include/idol/modeling/sparse-matrix/SparseVector.h include/idol/containers/sort.h + include/idol/modeling/solutions/Point.h ) find_package(OpenMP REQUIRED) diff --git a/lib/include/idol/containers/GeneratorPool.h b/lib/include/idol/containers/GeneratorPool.h index 8c11c677..c1775f66 100644 --- a/lib/include/idol/containers/GeneratorPool.h +++ b/lib/include/idol/containers/GeneratorPool.h @@ -5,14 +5,14 @@ #ifndef IDOL_GENERATORPOOL_H #define IDOL_GENERATORPOOL_H -#include "idol/modeling/solutions/Solution.h" +#include "idol/modeling/solutions/Point.h" #include namespace idol { template class GeneratorPool; } -template +template class idol::GeneratorPool { std::list> m_values; public: diff --git a/lib/include/idol/modeling/constraints/TempCtr.h b/lib/include/idol/modeling/constraints/TempCtr.h index e8f32c0a..3dbf88c2 100644 --- a/lib/include/idol/modeling/constraints/TempCtr.h +++ b/lib/include/idol/modeling/constraints/TempCtr.h @@ -117,7 +117,7 @@ class idol::TempCtr { * Returns true if the temporary constraint is violated by the given solution, false otherwise. * @param t_solution The solution to check. */ - [[nodiscard]] bool is_violated(const Solution::Primal& t_solution) const; + [[nodiscard]] bool is_violated(const PrimalPoint& t_solution) const; }; idol::TempCtr operator<=(idol::Expr&& t_lhs, idol::Expr&& t_rhs); diff --git a/lib/include/idol/modeling/expressions/AbstractExpr.h b/lib/include/idol/modeling/expressions/AbstractExpr.h index a63027c7..177c0192 100644 --- a/lib/include/idol/modeling/expressions/AbstractExpr.h +++ b/lib/include/idol/modeling/expressions/AbstractExpr.h @@ -46,7 +46,7 @@ class idol::impl::AbstractExpr { virtual void set(const Key& t_key, double t_coefficient); virtual double get(const Key& t_key) const; virtual void remove(const Key& t_key); - void internal_fix(const Solution::Primal& t_primals); + void internal_fix(const PrimalPoint& t_primals); class References; References refs(); @@ -169,7 +169,7 @@ class idol::impl::AbstractExpr { }; template -void idol::impl::AbstractExpr::internal_fix(const idol::Solution::Primal &t_primals) { +void idol::impl::AbstractExpr::internal_fix(const idol::PrimalPoint &t_primals) { for (auto& [key, ptr_to_value] : m_map) { ptr_to_value->value() = ptr_to_value->value().fix(t_primals); diff --git a/lib/include/idol/modeling/expressions/Constant.h b/lib/include/idol/modeling/expressions/Constant.h index 575610b7..04d8745e 100644 --- a/lib/include/idol/modeling/expressions/Constant.h +++ b/lib/include/idol/modeling/expressions/Constant.h @@ -9,6 +9,7 @@ #include "idol/modeling/parameters/Param.h" #include "idol/modeling/numericals.h" #include "idol/containers/IteratorForward.h" +#include "idol/modeling/solutions/Point.h" namespace idol { @@ -274,14 +275,14 @@ class idol::Constant { * @param t_primals Primal values associated to the stored `Param` * @return the resulting numerical */ - double fix(const Solution::Primal& t_primals) const; + double fix(const PrimalPoint& t_primals) const; /** * Computes the resulting numerical by replacing each `Param` by their corresponding values in `t_duals`. * @param t_primals Dual values associated to the stored `Param` * @return the resulting numerical */ - double fix(const Solution::Dual& t_duals) const; + double fix(const DualPoint& t_duals) const; void round(); diff --git a/lib/include/idol/modeling/expressions/Expr.h b/lib/include/idol/modeling/expressions/Expr.h index 2689c1ca..8807c73e 100644 --- a/lib/include/idol/modeling/expressions/Expr.h +++ b/lib/include/idol/modeling/expressions/Expr.h @@ -38,7 +38,7 @@ class idol::impl::Expr { References refs() { return References(this); } - void internal_fix(const Solution::Primal& t_primals); + void internal_fix(const PrimalPoint& t_primals); public: Expr(); Expr(double t_num); // NOLINT(google-explicit-constructor) @@ -229,11 +229,11 @@ class idol::Expr : public impl::Expr { Expr& operator=(const Expr& t_rhs) = default; Expr& operator=(Expr&&) noexcept = default; - Expr fix(const Solution::Primal& t_primals) const; + Expr fix(const PrimalPoint& t_primals) const; }; template -idol::Expr idol::Expr::fix(const Solution::Primal& t_primals) const { +idol::Expr idol::Expr::fix(const PrimalPoint& t_primals) const { auto result = *this; result.internal_fix(t_primals); return result; diff --git a/lib/include/idol/modeling/expressions/LinExpr.h b/lib/include/idol/modeling/expressions/LinExpr.h index c791a4a3..90ff00dd 100644 --- a/lib/include/idol/modeling/expressions/LinExpr.h +++ b/lib/include/idol/modeling/expressions/LinExpr.h @@ -84,11 +84,11 @@ class idol::LinExpr : public AbstractExpr> { */ void remove(const Key& t_key) override; - LinExpr fix(const Solution::Primal& t_primals) const; + LinExpr fix(const PrimalPoint& t_primals) const; }; template -idol::LinExpr idol::LinExpr::fix(const idol::Solution::Primal &t_primals) const { +idol::LinExpr idol::LinExpr::fix(const idol::PrimalPoint &t_primals) const { auto result = *this; result.internal_fix(t_primals); return result; diff --git a/lib/include/idol/modeling/expressions/operations/operators.h b/lib/include/idol/modeling/expressions/operations/operators.h index 5b85bec5..09f6f948 100644 --- a/lib/include/idol/modeling/expressions/operations/operators.h +++ b/lib/include/idol/modeling/expressions/operations/operators.h @@ -11,7 +11,7 @@ #include "operators_utils.h" namespace idol { - double evaluate(const Expr& t_expr, const Solution::Primal& t_values); + double evaluate(const Expr& t_expr, const PrimalPoint& t_values); } #endif //IDOL_OPERATORS_H diff --git a/lib/include/idol/modeling/matrix/Row.h b/lib/include/idol/modeling/matrix/Row.h index c324c553..59d1a80a 100644 --- a/lib/include/idol/modeling/matrix/Row.h +++ b/lib/include/idol/modeling/matrix/Row.h @@ -216,7 +216,7 @@ class idol::Row : public impl::Row { * @param t_primals The primal values. * @return The value of the row. */ - double value(const Solution::Primal& t_primals) const; + double value(const PrimalPoint& t_primals) const; /** * Returns true if the point stored in `t_primals` violates the constraint formed by the row and a constraint type @@ -226,7 +226,7 @@ class idol::Row : public impl::Row { * @param t_tolerance The tolerance for feasibility. * @return True if the given point violates the row. */ - bool is_violated(const Solution::Primal& t_primals, CtrType t_type, double t_tolerance = Tolerance::Feasibility) const; + bool is_violated(const PrimalPoint& t_primals, CtrType t_type, double t_tolerance = Tolerance::Feasibility) const; /** * Represents an empty row. diff --git a/lib/include/idol/modeling/models/Model.h b/lib/include/idol/modeling/models/Model.h index 302d7c42..5b804075 100644 --- a/lib/include/idol/modeling/models/Model.h +++ b/lib/include/idol/modeling/models/Model.h @@ -15,7 +15,7 @@ #include "idol/modeling/constraints/CtrVersion.h" #include "idol/modeling/variables/VarVersion.h" #include "idol/modeling/expressions/Expr.h" -#include "idol/modeling/solutions/Solution.h" +#include "idol/modeling/solutions/Point.h" #include "Model.h" @@ -1224,7 +1224,7 @@ namespace idol { static auto save_primal(const Model &t_original_model, const Model &t_model) { - Solution::Primal result; + PrimalPoint result; const auto status = t_model.get_status(); const auto reason = t_model.get_reason(); @@ -1252,7 +1252,7 @@ namespace idol { static auto save_ray(const Model &t_original_model, const Model &t_model) { - Solution::Primal result; + PrimalPoint result; const auto status = t_model.get_status(); const auto reason = t_model.get_reason(); @@ -1280,7 +1280,7 @@ namespace idol { static auto save_dual(const Model &t_original_model, const Model &t_model) { - Solution::Dual result; + DualPoint result; const auto status = t_model.get_status(); const auto reason = t_model.get_reason(); @@ -1308,7 +1308,7 @@ namespace idol { static auto save_farkas(const Model &t_original_model, const Model &t_model) { - Solution::Dual result; + DualPoint result; const auto status = t_model.get_status(); const auto reason = t_model.get_reason(); diff --git a/lib/include/idol/modeling/solutions/AbstractSolution.h b/lib/include/idol/modeling/solutions/AbstractSolution.h deleted file mode 100644 index 8f29a420..00000000 --- a/lib/include/idol/modeling/solutions/AbstractSolution.h +++ /dev/null @@ -1,338 +0,0 @@ -// -// Created by henri on 12/09/22. -// - -#ifndef OPTIMIZE_ABSTRACTSOLUTION_H -#define OPTIMIZE_ABSTRACTSOLUTION_H - -#include "idol/containers/Map.h" -#include "idol/containers/IteratorForward.h" -#include "types.h" -#include "idol/modeling/numericals.h" -#include "idol/optimizers/logs.h" -#include - -namespace idol { - template - class AbstractSolution; -} - -/** - * Base class for Solution::Primal and Solution::Dual. Stores a sparse vector of values associated to a given key. - * @tparam KeyT The type of the key (typically Var or Ctr) - * @tparam CRTP See [CRTP](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). - */ -template -class idol::AbstractSolution { - SolutionStatus m_status = Loaded; - SolutionReason m_reason = NotSpecified; - std::optional m_objective_value; - Map m_values; - - [[nodiscard]] double norm_inf() const; -public: - /** - * Default constructor. - * - * Creates a new empty solution. The status is set to `Loaded` and the reason to `NotSpecified`. - * No objective value nor solution entries is originally set. - */ - AbstractSolution() = default; - - virtual ~AbstractSolution() = default; - - AbstractSolution(const AbstractSolution&) = default; - AbstractSolution(AbstractSolution&&) noexcept = default; - - AbstractSolution& operator=(const AbstractSolution&) = default; - AbstractSolution& operator=(AbstractSolution&&) noexcept = default; - - /** - * Sets the solution status. - * @param t_status The desired solution status. - */ - void set_status(SolutionStatus t_status) { m_status = t_status; } - - /** - * Returns the stored solution status. - */ - [[nodiscard]] SolutionStatus status() const { return m_status; } - - /** - * Sets the reason for the solution status. - * - * **Example**: - * ```cpp - * solution.set_status(Feasible); - * solution.set_reason(IterLimit); // We only found a feasible solution because of iteration limit reached - * ``` - * @param t_reason The desired reason. - */ - void set_reason(SolutionReason t_reason) { m_reason = t_reason; } - - /** - * Returns the reason for the solution status. - * @return The reason for the solution status. - */ - [[nodiscard]] SolutionReason reason() const { return m_reason; } - - /** - * Sets the objective value of the solution. - * @param t_value The desired objective value. - */ - void set_objective_value(double t_value) { m_objective_value = t_value; } - - /** - * Returns the objective value of the solution. - */ - [[nodiscard]] double objective_value() const { return m_objective_value.value(); } - - /** - * Returns true if the solution has an objective value, false otherwise. - * @return True if the solution has an objective value, false otherwise. - */ - [[nodiscard]] bool has_objective_value() const { return m_objective_value.has_value(); } - - /** - * Resets the stored objective value. - * - * Trying to access the objective value after calling this method will throw an - * exception. - */ - void reset_objective_value() { m_objective_value.reset(); } - - /** - * Sets the value associated to the object `t_key` given as argument. - * @param t_key The key for which the entry should be set. - * @param t_value The desired value associated to the key. - */ - void set(const KeyT& t_key, double t_value); - - /** - * Returns the value associated to the object `t_key` given as argument. - * - * If no value is stored, zero is returned. - * @param t_key The queried key. - */ - [[nodiscard]] double get(const KeyT& t_key) const; - - /** - * Returns the number of non-zero entries in the solution. - * @return The number of non-zero entries in the solution - */ - [[nodiscard]] unsigned int size() const { return m_values.size(); } - - using const_iterator = typename Map::const_iterator; - - /** - * Returns an iterator on the values stored in the solution. - * @return An iterator on the values stored in the solution. - */ - const_iterator begin() const { return const_iterator(m_values.begin()); } - - /** - * Returns an iterator on the values stored in the solution. - * @return An iterator on the values stored in the solution. - */ - const_iterator end() const { return const_iterator(m_values.end()); } - - /** - * Returns an iterator on the values stored in the solution. - * @return An iterator on the values stored in the solution. - */ - const_iterator cbegin() const { return const_iterator(m_values.begin()); } - - /** - * Returns an iterator on the values stored in the solution. - * @return An iterator on the values stored in the solution. - */ - const_iterator cend() const { return const_iterator(m_values.end()); } - - /** - * Returns the \f$ l_p \f$-norm of the solution. - * - * Note that `Inf` is a possible value for `t_p`, in which case, the infinity norm is computed. - * @param t_p The \f$ p \f$ parameter in the \f$ l_p \f$-norm. - */ - [[nodiscard]] double norm(double t_p = 2.) const; - - /** - * Merges the solution with another solution, explicitly requiring that no conflict arises (i.e., that no - * entry from the solution `t_rhs` is already stored in the solution). - * If a conflict is detected, an exception is thrown. - * @param t_rhs The solution to merge. - * @return *this - */ - CRTP& merge_without_conflict(CRTP t_rhs); - - /** - * Normalizes the solution (i.e., divides every entry by the norm of the solution) with respect to a given \f$ l_p \f$-norm. - * @param t_p The parameter \f$ p \f$ for the norm. - * @return *this - */ - CRTP& normalize(double t_p = 2.); - - /** - * Rounds all the entries of the solution to the closest `double` with `t_n_digits`. - * - * Using `t_n_digits = 0` leads to the usual rounding, i.e., closest integer. - * @param t_n_digits The number of digits for the closest `double`. - * @return *this - */ - CRTP& round(unsigned int t_n_digits = 0); - - /** - * Adds the solution to another solution `t_rhs`. - * @param t_rhs The solution to add. - * @return *this - */ - CRTP& operator +=(const CRTP& t_rhs); - - /** - * Multiplies every entries in the solution by `t_factor`. - * @param t_factor The factor for multiplication. - * @return *this - */ - CRTP& operator *=(double t_factor); -}; - -template -void idol::AbstractSolution::set(const KeyT &t_key, double t_value) { - - if (equals(t_value, 0., Tolerance::Sparsity)) { - m_values.erase(t_key); - return; - } - - auto [it, success] = m_values.template emplace(t_key, t_value); - if (!success) { - it->second = t_value; - } - -} - -template -double idol::AbstractSolution::get(const KeyT &t_key) const { - auto it = m_values.find(t_key); - return it == m_values.end() ? 0. : it->second; -} - -template -CRTP& idol::AbstractSolution::normalize(double t_p) { - - const double scale = norm(t_p); - - if (m_objective_value.has_value()) { - m_objective_value.value() /= scale; - } - - for (auto& [key, value] : m_values) { - value /= scale; - } - - return dynamic_cast(*this); -} - -template -CRTP& idol::AbstractSolution::round(unsigned int t_n_digits) { - - for (auto& [key, value] : m_values) { - value = ::idol::round(value, t_n_digits); - } - - return dynamic_cast(*this); -} - -template -double idol::AbstractSolution::norm(double t_p) const { - - if (is_pos_inf(t_p)) { - return norm_inf(); - } - - double result = 0.; - for (const auto& [key, value] : m_values) { - result += std::pow(std::abs(value), t_p); - } - result = std::pow(result, 1 / t_p); - return result; -} - -template -double idol::AbstractSolution::norm_inf() const { - double result = -Inf; - for (const auto& [key, value] : m_values) { - if (double abs = std::abs(value) ; result < abs) { - result = abs; - } - } - return result; -} - -template -CRTP &idol::AbstractSolution::merge_without_conflict(CRTP t_rhs) { - for (const auto& [key, value] : t_rhs.m_values) { - auto [it, success] = m_values.template emplace(key, value); - if (!success) { - throw Exception("Conflicts were found while trying to merge explicitly \"without conflict\"."); - } - } - /* - m_values.template merge(t_rhs.m_values); - if (!t_rhs.m_values.empty()) { - throw Exception("Conflicts were found while trying to merge explicitly \"without conflict\"."); - } - */ - return dynamic_cast(*this); -} - -template -CRTP &idol::AbstractSolution::operator+=(const CRTP &t_rhs) { - for (const auto& [key, value] : t_rhs) { - auto [it, success] = m_values.template emplace(key, value); - if (!success) { - it->second += value; - if (equals(it->second, 0., Tolerance::Sparsity)) { - m_values.erase(it); - } - } - } - return dynamic_cast(*this); -} - -template -CRTP &idol::AbstractSolution::operator*=(double t_factor) { - - if (equals(t_factor, 0., Tolerance::Sparsity)) { - m_values.clear(); - return dynamic_cast(*this); - } - - for (auto& [key, value] : m_values) { - value *= t_factor; - } - - return dynamic_cast(*this); -} - -namespace idol { - - template - static std::ostream &operator<<(std::ostream &t_os, const idol::AbstractSolution &t_solution) { - t_os << "+-----------------------\n"; - t_os << "| Status: " << t_solution.status() << '\n'; - t_os << "| Reason: " << t_solution.reason() << '\n'; - if (t_solution.has_objective_value()) { - t_os << "| Objective: " << t_solution.objective_value() << '\n'; - } - t_os << "| Values:" << '\n'; - for (const auto &[key, value]: t_solution) { - t_os << "| \t" << std::setw(8) << key.name() << " = " << pretty_double(value) << '\n'; - } - t_os << "+-----------------------\n"; - return t_os; - } - -} - -#endif //OPTIMIZE_ABSTRACTSOLUTION_H diff --git a/lib/include/idol/modeling/solutions/Point.h b/lib/include/idol/modeling/solutions/Point.h new file mode 100644 index 00000000..36f5b5ec --- /dev/null +++ b/lib/include/idol/modeling/solutions/Point.h @@ -0,0 +1,71 @@ +// +// Created by henri on 24.10.24. +// + +#ifndef IDOL_POINT_H +#define IDOL_POINT_H + +#include "idol/modeling/sparse-matrix/SparseVector.h" +#include "types.h" +#include "idol/modeling/variables/Var.h" +#include "idol/modeling/numericals.h" + +namespace idol { + template class Point; + using PrimalPoint = Point; + using DualPoint = Point; +} + +template +class idol::Point : public SparseVector { + SolutionStatus m_status = Loaded; + SolutionReason m_reason = NotSpecified; + std::optional m_objective_value; +public: + Point() = default; + explicit Point(const SparseVector& t_vector) : SparseVector(t_vector) {} + explicit Point(SparseVector&& t_vector) : SparseVector(std::move(t_vector)) {} + + [[nodiscard]] SolutionStatus status() const { return m_status; } + void set_status(SolutionStatus t_status) { m_status = t_status; } + + [[nodiscard]] SolutionReason reason() const { return m_reason; } + + void set_reason(SolutionReason t_reason) { m_reason = t_reason; } + + [[nodiscard]] double objective_value() const; + + void set_objective_value(double t_objective_value) { m_objective_value = t_objective_value; } + + [[nodiscard]] bool has_objective_value() const { return m_objective_value.has_value(); } + + void reset_objective_value() { m_objective_value.reset(); } +}; + +template +double idol::Point::objective_value() const { + + if (m_objective_value.has_value()) { + return m_objective_value.value(); + } + + if (m_status == Unbounded) { + return -Inf; + } + + return Inf; +} + +namespace idol { + template + static std::ostream &operator<<(std::ostream &t_os, const Point &t_point) { + t_os << "Status: " << t_point.status() << '\n'; + t_os << "Reason: " << t_point.reason() << '\n'; + t_os << "Objective value: " << t_point.objective_value() << '\n'; + t_os << "Values: " << '\n'; + t_os << static_cast &>(t_point); + return t_os; + } +} + +#endif //IDOL_POINT_H diff --git a/lib/include/idol/modeling/solutions/Solution.h b/lib/include/idol/modeling/solutions/Solution.h deleted file mode 100644 index 88a67188..00000000 --- a/lib/include/idol/modeling/solutions/Solution.h +++ /dev/null @@ -1,87 +0,0 @@ -// -// Created by henri on 13/09/22. -// - -#ifndef OPTIMIZE_SOLUTION_H -#define OPTIMIZE_SOLUTION_H - -#include "idol/modeling/variables/Var.h" -#include "idol/modeling/constraints/Ctr.h" -#include "AbstractSolution.h" - -namespace idol::Solution { - - /** - * Primal solution class. - * - * This class is used to store a primal solution to an optimization problem. - * - * Typically, it is obtained by calling the `save_primal` function, or by creating a new solution from scratch. - * - * **Example 1**: - * ```cpp - * model.optimize(); - * if (model.get_status() == Optimal) { - * Solution::Primal solution = save_primal(model); - * std::cout << solution << std::endl; - * } - * ``` - * - * **Example 2**: - * ```cpp - * Solution::Primal solution; - * - * solution.set_status(Feasible); - * solution.set_objective_value(13.); - * solution.set(x, 1.); - * ``` - */ - class Primal : public AbstractSolution {}; - - /** - * Dual solution class. - * - * This class is used to store a dual solution to an optimization problem. - * - * Typically, it is obtained by calling the `save_dual` function, or by creating a new solution from scratch. - * - * **Example 1**: - * ```cpp - * model.optimize(); - * if (model.get_status() == Optimal) { - * Solution::Dual solution = save_dual(model); - * std::cout << solution << std::endl; - * } - * ``` - * - * **Example 2**: - * ```cpp - * Solution::Dual solution; - * - * solution.set_status(Feasible); - * solution.set_objective_value(13.); - * solution.set(constraint_1, -100.); - * ``` - */ - class Dual : public AbstractSolution {}; - - - static Solution::Primal operator+(Solution::Primal t_a, const Solution::Primal& t_b) { - return t_a += t_b; - } - - static Solution::Dual operator+(Solution::Dual t_a, const Solution::Dual& t_b) { - return t_a += t_b; - } - - static Solution::Primal operator*(double t_factor, Solution::Primal t_solution) { - return t_solution *= t_factor; - } - - static Solution::Dual operator*(double t_factor, Solution::Dual t_solution) { - return t_solution *= t_factor; - } - -} - -#endif //OPTIMIZE_SOLUTION_H diff --git a/lib/include/idol/modeling/sparse-matrix/SparseVector.h b/lib/include/idol/modeling/sparse-matrix/SparseVector.h index 8daaaaff..b52e0fef 100644 --- a/lib/include/idol/modeling/sparse-matrix/SparseVector.h +++ b/lib/include/idol/modeling/sparse-matrix/SparseVector.h @@ -96,6 +96,41 @@ class idol::SparseVector { const std::vector& get_indices() const { return m_indices; } const std::vector& get_values() const { return m_values; } + + class iterator { + unsigned int m_index; + SparseVector& m_vector; + public: + iterator(unsigned int t_index, SparseVector& t_vector) : m_index(t_index), m_vector(t_vector) {} + iterator& operator++() { ++m_index; return *this; } + [[nodiscard]] bool operator==(const iterator& t_other) const { return m_index == t_other.m_index; } + [[nodiscard]] bool operator!=(const iterator& t_other) const { return m_index != t_other.m_index; } + [[nodiscard]] std::pair operator*() const { return {m_vector.index_at(m_index), m_vector.value_at(m_index)}; } + }; + + class const_iterator { + unsigned int m_index; + const SparseVector &m_vector; + public: + const_iterator(unsigned int t_index, const SparseVector &t_vector) : m_index(t_index), m_vector(t_vector) {} + const_iterator& operator++() { ++m_index; return *this; } + [[nodiscard]] bool operator==(const const_iterator& t_other) const { return m_index == t_other.m_index; } + [[nodiscard]] bool operator!=(const const_iterator& t_other) const { return m_index != t_other.m_index; } + [[nodiscard]] std::pair operator*() const { return {m_vector.index_at(m_index), m_vector.value_at(m_index)}; } + }; + + [[nodiscard]] iterator begin() { return iterator(0, *this); } + + [[nodiscard]] iterator end() { return iterator(size(), *this); } + + [[nodiscard]] const_iterator begin() const { return const_iterator(0, *this); } + + [[nodiscard]] const_iterator end() const { return const_iterator(size(), *this); } + + [[nodiscard]] const_iterator cbegin() const { return const_iterator(0, *this); } + + [[nodiscard]] const_iterator cend() const { return const_iterator(size(), *this); } + }; template @@ -202,7 +237,13 @@ void idol::SparseVector::set(const IndexT &t_in [](const IndexT& t_index1, const IndexT& t_index2) { return IndexExtractorT()(t_index1) < IndexExtractorT()(t_index2); } ); - if (it == m_indices.end() || IndexExtractorT()(*it) != IndexExtractorT()(t_index)) { + if (it == m_indices.end()) { + m_indices.emplace_back(t_index); + m_values.emplace_back(t_value); + return; + } + + if (IndexExtractorT()(*it) != IndexExtractorT()(t_index)) { m_indices.insert(it, t_index); m_values.insert(m_values.begin() + (it - m_indices.begin()), t_value); return; @@ -271,7 +312,13 @@ void idol::SparseVector::set(const IndexT &t_in [](const IndexT& t_index1, const IndexT& t_index2) { return IndexExtractorT()(t_index1) < IndexExtractorT()(t_index2); } ); - if (it == m_indices.end() || IndexExtractorT()(*it) != IndexExtractorT()(t_index)) { + if (it == m_indices.end()) { + m_indices.emplace_back(t_index); + m_values.emplace_back(t_value); + return; + } + + if (IndexExtractorT()(*it) != IndexExtractorT()(t_index)) { m_indices.insert(it, t_index); m_values.insert(m_values.begin() + (it - m_indices.begin()), t_value); return; @@ -596,17 +643,19 @@ void idol::SparseVector::remove(const IndexT &t } -template -std::ostream &operator<<(std::ostream &t_stream, const idol::SparseVector &t_vector) { +namespace idol { + template + static std::ostream & operator<<(std::ostream &t_stream, const idol::SparseVector &t_vector) { - const auto& indices = t_vector.get_indices(); - const auto& values = t_vector.get_values(); + const auto &indices = t_vector.get_indices(); + const auto &values = t_vector.get_values(); - for (unsigned int i = 0, n = t_vector.size() ; i < n ; ++i) { - t_stream << indices[i] << ": " << values[i] << '\n'; - } + for (unsigned int i = 0, n = t_vector.size(); i < n; ++i) { + t_stream << indices[i] << ": " << values[i] << '\n'; + } - return t_stream; + return t_stream; + } } #endif //IDOL_SPARSEVECTOR_H diff --git a/lib/include/idol/optimizers/Algorithm.h b/lib/include/idol/optimizers/Algorithm.h index fc0b352e..2be82883 100644 --- a/lib/include/idol/optimizers/Algorithm.h +++ b/lib/include/idol/optimizers/Algorithm.h @@ -6,7 +6,7 @@ #define IDOL_ALGORITHM_H #include "Optimizer.h" -#include "idol/modeling/solutions/Solution.h" +#include "idol/modeling/solutions/Point.h" namespace idol { class Algorithm; diff --git a/lib/include/idol/optimizers/bilevel-optimization/wrappers/MibS/MibSCallbackI.h b/lib/include/idol/optimizers/bilevel-optimization/wrappers/MibS/MibSCallbackI.h index 2e7efd15..c37e0887 100644 --- a/lib/include/idol/optimizers/bilevel-optimization/wrappers/MibS/MibSCallbackI.h +++ b/lib/include/idol/optimizers/bilevel-optimization/wrappers/MibS/MibSCallbackI.h @@ -38,11 +38,11 @@ class idol::MibSCallbackI : public CallbackI { public: class Heuristic : public ::BlisHeuristic { MibSCallbackI& m_parent; - std::list m_solutions; + std::list m_solutions; public: explicit Heuristic(MibSCallbackI& t_parent) : m_parent(t_parent) {} - void submit_heuristic_solution(Solution::Primal t_solution) { + void submit_heuristic_solution(PrimalPoint t_solution) { m_solutions.emplace_back(std::move(t_solution)); } @@ -51,7 +51,7 @@ class idol::MibSCallbackI : public CallbackI { m_parent.m_is_heuristic_call = true; m_parent.call(InvalidSolution); - std::list::iterator solution = m_solutions.end(); + std::list::iterator solution = m_solutions.end(); double current_best = m_parent.best_obj(); for (auto it = m_solutions.begin(), end = m_solutions.end(); it != end ; ++it) { if (it->objective_value() < current_best) { @@ -160,17 +160,17 @@ class idol::MibSCallbackI : public CallbackI { throw Exception("Not implemented."); } - void submit_heuristic_solution(Solution::Primal t_solution) override { + void submit_heuristic_solution(PrimalPoint t_solution) override { m_heuristic->submit_heuristic_solution(std::move(t_solution)); } - [[nodiscard]] Solution::Primal primal_solution() const override { + [[nodiscard]] PrimalPoint primal_solution() const override { auto& osi_solver = *m_parent.m_osi_solver; const auto* solution = osi_solver.getColSolution(); const unsigned int n_vars = osi_solver.getNumCols(); - Solution::Primal result; + PrimalPoint result; result.set_reason(NotSpecified); if (osi_solver.isProvenOptimal()) { diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/branching-rules/impls/BranchingWithPriority.h b/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/branching-rules/impls/BranchingWithPriority.h index e911eed9..b6fd808a 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/branching-rules/impls/BranchingWithPriority.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/branching-rules/impls/BranchingWithPriority.h @@ -9,7 +9,7 @@ #include #include "BranchingRule.h" #include "idol/modeling/variables/Var.h" -#include "idol/modeling/solutions/Solution.h" +#include "idol/modeling/solutions/Point.h" #include "idol/optimizers/mixed-integer-optimization/branch-and-bound/branching-rules/factories/BranchingRuleFactory.h" namespace idol::BranchingRules { diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/branching-rules/impls/VariableBranching.h b/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/branching-rules/impls/VariableBranching.h index 2ce3b469..8a7cb08b 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/branching-rules/impls/VariableBranching.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/branching-rules/impls/VariableBranching.h @@ -8,7 +8,7 @@ #include #include "BranchingRule.h" #include "idol/modeling/variables/Var.h" -#include "idol/modeling/solutions/Solution.h" +#include "idol/modeling/solutions/Point.h" namespace idol::BranchingRules { template @@ -80,7 +80,7 @@ class idol::BranchingRules::VariableBranching : public BranchingRule } protected: - std::list get_invalid_variables(const Solution::Primal& t_primal_solution) { + std::list get_invalid_variables(const PrimalPoint& t_primal_solution) { std::list result; diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/callbacks/AbstractBranchAndBoundCallbackI.h b/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/callbacks/AbstractBranchAndBoundCallbackI.h index f146383c..d0391322 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/callbacks/AbstractBranchAndBoundCallbackI.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/callbacks/AbstractBranchAndBoundCallbackI.h @@ -5,7 +5,7 @@ #ifndef IDOL_ABSTRACTBRANCHANDBOUNDCALLBACKI_H #define IDOL_ABSTRACTBRANCHANDBOUNDCALLBACKI_H -#include "idol/modeling/solutions/Solution.h" +#include "idol/modeling/solutions/Point.h" #include "idol/optimizers/mixed-integer-optimization/callbacks/Callback.h" namespace idol { diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/callbacks/CallbackAsBranchAndBoundCallback.h b/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/callbacks/CallbackAsBranchAndBoundCallback.h index 445432e1..15f5092b 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/callbacks/CallbackAsBranchAndBoundCallback.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/callbacks/CallbackAsBranchAndBoundCallback.h @@ -46,13 +46,13 @@ class idol::CallbackAsBranchAndBoundCallback : public BranchAndBoundCallbackFact m_parent.add_lazy_cut(t_cut); } - void submit_heuristic_solution(Solution::Primal t_solution) override { + void submit_heuristic_solution(PrimalPoint t_solution) override { auto* info = new NodeInfoT(); info->set_primal_solution(std::move(t_solution)); m_parent.submit_heuristic_solution(info); } - [[nodiscard]] Solution::Primal primal_solution() const override { + [[nodiscard]] PrimalPoint primal_solution() const override { return m_parent.node().info().primal_solution(); } diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/logs/Info.h b/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/logs/Info.h index c294a0b2..fc3c131b 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/logs/Info.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/logs/Info.h @@ -6,6 +6,7 @@ #define IDOL_BRANCHANDBOUND_INFO_H #include "Factory.h" +#include "idol/optimizers/logs.h" namespace idol::Logs::BranchAndBound { template class Info; diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/nodes/DefaultNodeInfo.h b/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/nodes/DefaultNodeInfo.h index 76dc11b1..939c1029 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/nodes/DefaultNodeInfo.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/branch-and-bound/nodes/DefaultNodeInfo.h @@ -36,7 +36,7 @@ class idol::DefaultNodeInfo { [[nodiscard]] const auto& primal_solution() const { return m_primal_solution; } - void set_primal_solution(Solution::Primal t_primal_solution) { m_primal_solution = std::move(t_primal_solution); } + void set_primal_solution(PrimalPoint t_primal_solution) { m_primal_solution = std::move(t_primal_solution); } virtual void save(const Model& t_original_formulation, const Model& t_model); @@ -52,7 +52,7 @@ class idol::DefaultNodeInfo { static DefaultNodeUpdator* create_updator(Model& t_relaxation); private: - Solution::Primal m_primal_solution; + PrimalPoint m_primal_solution; std::optional m_sum_of_infeasibilities; std::list m_variable_branching_decisions; std::list m_constraint_branching_decisions; diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/callbacks/Callback.h b/lib/include/idol/optimizers/mixed-integer-optimization/callbacks/Callback.h index 44416516..c823ee88 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/callbacks/Callback.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/callbacks/Callback.h @@ -5,7 +5,7 @@ #ifndef IDOL_CALLBACK_H #define IDOL_CALLBACK_H -#include "idol/modeling/solutions/Solution.h" +#include "idol/modeling/solutions/Point.h" namespace idol { class TempCtr; @@ -49,9 +49,9 @@ class idol::CallbackI { virtual void add_lazy_cut(const TempCtr& t_cut) = 0; - virtual void submit_heuristic_solution(Solution::Primal t_solution) = 0; + virtual void submit_heuristic_solution(PrimalPoint t_solution) = 0; - [[nodiscard]] virtual Solution::Primal primal_solution() const = 0; + [[nodiscard]] virtual PrimalPoint primal_solution() const = 0; [[nodiscard]] virtual const Timer& time() const = 0; @@ -79,7 +79,7 @@ class idol::Callback { /** * Submits a new heuristic solution */ - virtual void submit_heuristic_solution(const Solution::Primal& t_solution); + virtual void submit_heuristic_solution(const PrimalPoint& t_solution); /** * Adds a user cut to the relaxation @@ -97,7 +97,7 @@ class idol::Callback { * Returns the solution of the node which is currently being explored (when available) * @return the solution of the current node */ - [[nodiscard]] virtual Solution::Primal primal_solution() const; + [[nodiscard]] virtual PrimalPoint primal_solution() const; /** * Returns the current time diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/callbacks/cutting-planes/CutSeparation.h b/lib/include/idol/optimizers/mixed-integer-optimization/callbacks/cutting-planes/CutSeparation.h index 94fb6eb0..4614673c 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/callbacks/cutting-planes/CutSeparation.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/callbacks/cutting-planes/CutSeparation.h @@ -19,7 +19,7 @@ class idol::impl::CutSeparation : public Callback { double m_tolerance = idol::Tolerance::Feasibility; protected: - std::pair<::idol::Expr, ObjectiveSense> create_separation_objective(const Solution::Primal& t_primal_solution); + std::pair<::idol::Expr, ObjectiveSense> create_separation_objective(const PrimalPoint& t_primal_solution); void operator()(CallbackEvent t_event) override; diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/ColumnGeneration.h b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/ColumnGeneration.h index 8f0bb26a..2c5ae7d9 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/ColumnGeneration.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/ColumnGeneration.h @@ -13,8 +13,8 @@ class idol::Optimizers::DantzigWolfeDecomposition::ColumnGeneration { SolutionStatus m_status = Loaded; SolutionReason m_reason = NotSpecified; - std::optional m_master_primal_solution; - std::optional m_last_master_solution; + std::optional m_master_primal_solution; + std::optional m_last_master_solution; std::vector m_sub_problems_phases; double m_best_obj = -Inf; double m_best_bound = +Inf; @@ -55,7 +55,7 @@ class idol::Optimizers::DantzigWolfeDecomposition::ColumnGeneration { double best_bound() const { return m_best_bound; } - const Solution::Primal& primal_solution() const { return m_master_primal_solution.value(); } + const PrimalPoint& primal_solution() const { return m_master_primal_solution.value(); } void set_best_bound_stop(double t_best_bound_stop) { m_best_bound_stop = t_best_bound_stop; } diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/Formulation.h b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/Formulation.h index 764bbf08..5048bc1d 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/Formulation.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/Formulation.h @@ -13,7 +13,7 @@ namespace idol::DantzigWolfe { } class idol::DantzigWolfe::Formulation { - using PresentGeneratorsList = std::list>; + using PresentGeneratorsList = std::list>; Annotation m_decomposition_by_ctr; Annotation m_decomposition_by_var; @@ -38,7 +38,7 @@ class idol::DantzigWolfe::Formulation { void dispatch_linking_constraint(const Ctr& t_original_ctr, const Row& t_row, CtrType t_type); std::pair, std::vector> decompose_expression(const LinExpr &t_linear, const QuadExpr& t_quadratic); void dispatch_objective_function(const Model& t_original_formulation); - bool is_feasible(const Solution::Primal& t_primal, unsigned int t_sub_problem_id); + bool is_feasible(const PrimalPoint& t_primal, unsigned int t_sub_problem_id); void apply_sub_problem_bound_on_master(bool t_is_lb, const idol::Var &t_var, unsigned int t_sub_problem_id, double t_value); LinExpr reformulate_sub_problem_variable(const Var &t_var, unsigned int t_sub_problem_id); @@ -76,19 +76,19 @@ class idol::DantzigWolfe::Formulation { void add_aggregation_constraint(unsigned int t_sub_problem_id, double t_lower_multiplicity, double t_upper_multiplicity); - void update_sub_problem_objective(unsigned int t_sub_problem_id, const Solution::Dual& t_master_dual, bool t_use_farkas = false); + void update_sub_problem_objective(unsigned int t_sub_problem_id, const DualPoint& t_master_dual, bool t_use_farkas = false); - void generate_column(unsigned int t_sub_problem_id, Solution::Primal t_generator); + void generate_column(unsigned int t_sub_problem_id, PrimalPoint t_generator); - double compute_reduced_cost(unsigned int t_sub_problem_id, const Solution::Dual& t_master_dual, const Solution::Primal& t_generator); + double compute_reduced_cost(unsigned int t_sub_problem_id, const DualPoint& t_master_dual, const PrimalPoint& t_generator); - double get_original_space_var_primal(const Var& t_var, const Solution::Primal& t_master_primal) const; + double get_original_space_var_primal(const Var& t_var, const PrimalPoint& t_master_primal) const; void update_var_lb(const Var& t_var, double t_lb, bool t_hard, bool t_remove_infeasible_columns); void update_var_ub(const Var& t_var, double t_ub, bool t_hard, bool t_remove_infeasible_columns); - void remove_column_if(unsigned int t_sub_problem_id, const std::function &t_indicator_for_removal); + void remove_column_if(unsigned int t_sub_problem_id, const std::function &t_indicator_for_removal); void update_obj(const Expr& t_expr); diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/ArtificialCosts.h b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/ArtificialCosts.h index 01ee1b86..27a4b639 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/ArtificialCosts.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/ArtificialCosts.h @@ -30,8 +30,8 @@ class idol::DantzigWolfe::ArtificialCosts : public idol::DantzigWolfe::Infeasibi void create_artificial_variables(DantzigWolfe::Formulation& t_formulation); void find_initial_columns(idol::Optimizers::DantzigWolfeDecomposition::ColumnGeneration &t_column_generation); void delete_artificial_variables(DantzigWolfe::Formulation& t_formulation); - bool all_artificial_variables_are_non_basic(const Solution::Primal &t_primal_values) const; - void update_objective_function(DantzigWolfe::Formulation& t_formulation, const Solution::Primal& t_primal_values, bool t_include_original_objective_function); + bool all_artificial_variables_are_non_basic(const PrimalPoint &t_primal_values) const; + void update_objective_function(DantzigWolfe::Formulation& t_formulation, const PrimalPoint& t_primal_values, bool t_include_original_objective_function); void restore_objective_function(DantzigWolfe::Formulation& t_formulation); public: Strategy(double t_initial_costs, double t_update_factor, unsigned int t_max_updates_before_phase_I); diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/DantzigWolfeInfeasibilityStrategy.h b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/DantzigWolfeInfeasibilityStrategy.h index e38ea02e..9ed69c0a 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/DantzigWolfeInfeasibilityStrategy.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/DantzigWolfeInfeasibilityStrategy.h @@ -6,7 +6,7 @@ #define IDOL_DANTZIGWOLFEINFEASIBILITYSTRATEGY_H #include "idol/modeling/solutions/types.h" -#include "idol/modeling/solutions/Solution.h" +#include "idol/modeling/solutions/Point.h" namespace idol::Optimizers { class DantzigWolfeDecomposition; @@ -25,7 +25,7 @@ class idol::DantzigWolfe::InfeasibilityStrategyFactory { SolutionReason m_reason = NotSpecified; std::optional m_best_obj; std::optional m_best_bound; - std::optional m_primal_solution; + std::optional m_primal_solution; public: virtual ~Strategy() = default; @@ -39,13 +39,13 @@ class idol::DantzigWolfe::InfeasibilityStrategyFactory { double best_bound() const { return m_best_bound.value(); } - const Solution::Primal& primal_solution() const; + const PrimalPoint& primal_solution() const; protected: void set_status(SolutionStatus t_status) { m_status = t_status; } void set_reason(SolutionReason t_reason) { m_reason = t_reason; } - void set_primal_solution(Solution::Primal t_solution) { m_primal_solution = std::move(t_solution); } + void set_primal_solution(PrimalPoint t_solution) { m_primal_solution = std::move(t_solution); } void set_best_obj(double t_best_obj) { m_best_obj = t_best_obj; } diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/DualPriceSmoothingStabilization.h b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/DualPriceSmoothingStabilization.h index d2ff094d..ad045316 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/DualPriceSmoothingStabilization.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/DualPriceSmoothingStabilization.h @@ -5,7 +5,7 @@ #ifndef IDOL_DUALPRICESMOOTHINGSTABILIZATION_H #define IDOL_DUALPRICESMOOTHINGSTABILIZATION_H -#include "idol/modeling/solutions/Solution.h" +#include "idol/modeling/solutions/Point.h" namespace idol::DantzigWolfe { class DualPriceSmoothingStabilization; @@ -21,9 +21,9 @@ class idol::DantzigWolfe::DualPriceSmoothingStabilization { virtual void initialize() = 0; - virtual void update_stability_center(const Solution::Dual& t_master_dual) = 0; + virtual void update_stability_center(const DualPoint& t_master_dual) = 0; - virtual Solution::Dual compute_smoothed_dual_solution(const Solution::Dual& t_master_dual) = 0; + virtual DualPoint compute_smoothed_dual_solution(const DualPoint& t_master_dual) = 0; }; virtual Strategy* operator()() const = 0; diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/Neame.h b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/Neame.h index 89488838..64ef2b37 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/Neame.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/Neame.h @@ -18,7 +18,7 @@ class idol::DantzigWolfe::Neame : public DualPriceSmoothingStabilization { class Strategy : public DualPriceSmoothingStabilization::Strategy { double m_factor; - std::optional m_smoothed_dual; + std::optional m_smoothed_dual; public: explicit Strategy(double t_initial_factor) : m_factor(t_initial_factor) {} @@ -26,11 +26,11 @@ class idol::DantzigWolfe::Neame : public DualPriceSmoothingStabilization { m_smoothed_dual.reset(); } - void update_stability_center(const Solution::Dual &t_master_dual) override { + void update_stability_center(const DualPoint &t_master_dual) override { // intentionally left blank } - Solution::Dual compute_smoothed_dual_solution(const Solution::Dual &t_master_dual) override { + DualPoint compute_smoothed_dual_solution(const DualPoint &t_master_dual) override { if (!m_smoothed_dual.has_value() || m_factor <= 1e-4) { m_smoothed_dual = t_master_dual; diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/NoStabilization.h b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/NoStabilization.h index 817f0dd1..26c362f6 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/NoStabilization.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/NoStabilization.h @@ -23,11 +23,11 @@ class idol::DantzigWolfe::NoStabilization : public DualPriceSmoothingStabilizati // intentionally left blank } - void update_stability_center(const Solution::Dual &t_master_dual) override { + void update_stability_center(const DualPoint &t_master_dual) override { // intentionally left blank } - Solution::Dual compute_smoothed_dual_solution(const Solution::Dual &t_master_dual) override { + DualPoint compute_smoothed_dual_solution(const DualPoint &t_master_dual) override { return t_master_dual; } diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/Wentges.h b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/Wentges.h index d2a2c552..e91d40ef 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/Wentges.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/dantzig-wolfe/stabilization/Wentges.h @@ -19,7 +19,7 @@ class idol::DantzigWolfe::Wentges : public DualPriceSmoothingStabilization { class Strategy : public DualPriceSmoothingStabilization::Strategy { double m_factor; - std::optional m_stability_center; + std::optional m_stability_center; public: explicit Strategy(double t_initial_factor) : m_factor(t_initial_factor) {} @@ -27,11 +27,11 @@ class idol::DantzigWolfe::Wentges : public DualPriceSmoothingStabilization { m_stability_center.reset(); } - void update_stability_center(const Solution::Dual &t_master_dual) override { + void update_stability_center(const DualPoint &t_master_dual) override { m_stability_center = t_master_dual; } - Solution::Dual compute_smoothed_dual_solution(const Solution::Dual &t_master_dual) override { + DualPoint compute_smoothed_dual_solution(const DualPoint &t_master_dual) override { if (!m_stability_center.has_value() || m_factor <= 1e-4) { m_stability_center = t_master_dual; diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/padm/Formulation.h b/lib/include/idol/optimizers/mixed-integer-optimization/padm/Formulation.h index ed4a6b27..5a44eb43 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/padm/Formulation.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/padm/Formulation.h @@ -44,11 +44,11 @@ class idol::ADM::Formulation { bool has_penalized_constraints() const { return m_penalized_constraints.has_value(); } - void fix_sub_problem(unsigned int t_sub_problem_id, const std::vector& t_primals); + void fix_sub_problem(unsigned int t_sub_problem_id, const std::vector& t_primals); void initialize_penalty_parameters(double t_value); - bool update_penalty_parameters(const std::vector& t_primals, PenaltyUpdate& t_penalty_update); // Returns true if penalty parameters have been resacled + bool update_penalty_parameters(const std::vector& t_primals, PenaltyUpdate& t_penalty_update); // Returns true if penalty parameters have been resacled struct CurrentPenalty { const Ctr constraint; @@ -83,10 +83,10 @@ class idol::ADM::Formulation { std::pair, bool> dispatch(const Model& t_src_model, const LinExpr& t_lin_expr, const QuadExpr& t_quad_expr, unsigned int t_sub_problem_id); Var get_or_create_l1_var(const Ctr& t_ctr); void set_penalty_in_all_sub_problems(const Var& t_var, double t_value); - void update_penalty_parameters_independently(const std::vector& t_primals, PenaltyUpdate& t_penalty_update); + void update_penalty_parameters_independently(const std::vector& t_primals, PenaltyUpdate& t_penalty_update); bool rescale_penalty_parameters(std::list& t_penalties); - double fix(const Constant& t_constant, const std::vector& t_primals); + double fix(const Constant& t_constant, const std::vector& t_primals); }; diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/padm/Optimizers_PADM.h b/lib/include/idol/optimizers/mixed-integer-optimization/padm/Optimizers_PADM.h index aae67b02..1a5c692d 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/padm/Optimizers_PADM.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/padm/Optimizers_PADM.h @@ -96,8 +96,8 @@ class idol::Optimizers::PADM : public Algorithm { void make_history(); void log_inner_loop(unsigned int t_inner_loop_iteration); void log_outer_loop(); - double infeasibility_linf(unsigned int t_sub_problem_id, const Solution::Primal& t_solution) const; - double infeasibility_l1(unsigned int t_sub_problem_id, const Solution::Primal& t_solution) const; + double infeasibility_linf(unsigned int t_sub_problem_id, const PrimalPoint& t_solution) const; + double infeasibility_l1(unsigned int t_sub_problem_id, const PrimalPoint& t_solution) const; void detect_stagnation(bool t_feasibility_has_changed); void detect_stagnation_due_to_rescaling(); void restart(); @@ -127,7 +127,7 @@ class idol::Optimizers::PADM : public Algorithm { unsigned int m_n_restart = 0; unsigned int m_outer_loop_iteration = 0; unsigned int m_inner_loop_iterations = 0; - std::vector m_last_solutions; + std::vector m_last_solutions; double m_current_initial_penalty_parameter = m_initial_penalty_parameter; struct IterationLog { diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/padm/SubProblem.h b/lib/include/idol/optimizers/mixed-integer-optimization/padm/SubProblem.h index d39e5621..11348307 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/padm/SubProblem.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/padm/SubProblem.h @@ -6,7 +6,7 @@ #define IDOL_ADM_SUBPROBLEM_H #include "idol/optimizers/OptimizerFactory.h" -#include "idol/modeling/solutions/Solution.h" +#include "idol/modeling/solutions/Point.h" #include namespace idol::ADM { @@ -15,7 +15,7 @@ namespace idol::ADM { class idol::ADM::SubProblem { std::unique_ptr m_optimizer_factory; - std::optional m_initial_point; + std::optional m_initial_point; public: SubProblem() = default; @@ -27,11 +27,11 @@ class idol::ADM::SubProblem { SubProblem& with_optimizer(const OptimizerFactory& t_optimizer_factory); - SubProblem& with_initial_point(const Solution::Primal& t_initial_point); + SubProblem& with_initial_point(const PrimalPoint& t_initial_point); const OptimizerFactory& optimizer_factory() const; - Solution::Primal initial_point() const; + PrimalPoint initial_point() const; }; diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/wrappers/GLPK/Optimizers_GLPK.h b/lib/include/idol/optimizers/mixed-integer-optimization/wrappers/GLPK/Optimizers_GLPK.h index a77345da..6ab5a7b2 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/wrappers/GLPK/Optimizers_GLPK.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/wrappers/GLPK/Optimizers_GLPK.h @@ -28,8 +28,8 @@ class idol::Optimizers::GLPK : public OptimizerWithLazyUpdates { SolutionStatus m_solution_status = Loaded; SolutionReason m_solution_reason = NotSpecified; - std::optional m_unbounded_ray; - std::optional m_farkas_certificate; + std::optional m_unbounded_ray; + std::optional m_farkas_certificate; std::stack m_deleted_variables; std::stack m_deleted_constraints; diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/wrappers/Gurobi/GurobiCallbackI.h b/lib/include/idol/optimizers/mixed-integer-optimization/wrappers/Gurobi/GurobiCallbackI.h index 81eea10a..523a20d5 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/wrappers/Gurobi/GurobiCallbackI.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/wrappers/Gurobi/GurobiCallbackI.h @@ -41,9 +41,9 @@ class idol::GurobiCallbackI : public GRBCallback, public CallbackI { void add_user_cut(const TempCtr& t_user_cut) override; - void submit_heuristic_solution(Solution::Primal t_solution) override; + void submit_heuristic_solution(PrimalPoint t_solution) override; - [[nodiscard]] Solution::Primal primal_solution() const override; + [[nodiscard]] PrimalPoint primal_solution() const override; [[nodiscard]] const Timer &time() const override; diff --git a/lib/include/idol/optimizers/mixed-integer-optimization/wrappers/Mosek/MosekCallbackI.h b/lib/include/idol/optimizers/mixed-integer-optimization/wrappers/Mosek/MosekCallbackI.h index 46593b62..8617d997 100644 --- a/lib/include/idol/optimizers/mixed-integer-optimization/wrappers/Mosek/MosekCallbackI.h +++ b/lib/include/idol/optimizers/mixed-integer-optimization/wrappers/Mosek/MosekCallbackI.h @@ -42,9 +42,9 @@ class idol::MosekCallbackI : public CallbackI { void add_lazy_cut(const TempCtr &t_cut) override; - void submit_heuristic_solution(Solution::Primal t_solution) override; + void submit_heuristic_solution(PrimalPoint t_solution) override; - Solution::Primal primal_solution() const override; + PrimalPoint primal_solution() const override; const Timer &time() const override; diff --git a/lib/src/modeling/constraints/TempCtr.cpp b/lib/src/modeling/constraints/TempCtr.cpp index b50a1a25..30cf2c4a 100644 --- a/lib/src/modeling/constraints/TempCtr.cpp +++ b/lib/src/modeling/constraints/TempCtr.cpp @@ -2,7 +2,7 @@ // Created by henri on 08/09/22. // #include "idol/modeling/constraints/TempCtr.h" -#include "idol/modeling/solutions/Solution.h" +#include "idol/modeling/solutions/Point.h" #include "idol/modeling/expressions/LinExpr.h" using namespace idol; @@ -31,7 +31,7 @@ TempCtr operator==(const Expr& t_lhs, Expr&& t_rhs) { return Expr TempCtr operator==(Expr&& t_lhs, const Expr& t_rhs) { return std::move(t_lhs) == Expr(t_rhs); } TempCtr operator==(const Expr& t_lhs, const Expr& t_rhs) { return Expr(t_lhs) == Expr(t_rhs); } -bool TempCtr::is_violated(const Solution::Primal &t_solution) const { +bool TempCtr::is_violated(const PrimalPoint &t_solution) const { const double rhs = m_row.rhs(); double lhs = 0.; for (const auto& [var, coeff] : m_row.linear()) { diff --git a/lib/src/modeling/expressions/Constant.cpp b/lib/src/modeling/expressions/Constant.cpp index 415ced9a..27a2c29d 100644 --- a/lib/src/modeling/expressions/Constant.cpp +++ b/lib/src/modeling/expressions/Constant.cpp @@ -3,7 +3,7 @@ // #include "idol/modeling/expressions/Constant.h" #include "idol/modeling/numericals.h" -#include "idol/modeling/solutions/Solution.h" +#include "idol/modeling/solutions/Point.h" #include idol::Constant idol::Constant::Zero; @@ -252,7 +252,7 @@ bool idol::Constant::is_numerical() const { return (!m_linear_terms || m_linear_terms->empty()) && (!m_quadratic_terms || m_quadratic_terms->empty()); } -double idol::Constant::fix(const Solution::Primal &t_primals) const { +double idol::Constant::fix(const PrimalPoint &t_primals) const { double result = m_constant; if (m_linear_terms) { @@ -275,7 +275,7 @@ double idol::Constant::fix(const Solution::Primal &t_primals) const { return result; } -double idol::Constant::fix(const Solution::Dual &t_duals) const { +double idol::Constant::fix(const DualPoint &t_duals) const { double result = m_constant; if (m_linear_terms) { diff --git a/lib/src/modeling/expressions/operations/operators.cpp b/lib/src/modeling/expressions/operations/operators.cpp index 01bb9fe4..a1345825 100644 --- a/lib/src/modeling/expressions/operations/operators.cpp +++ b/lib/src/modeling/expressions/operations/operators.cpp @@ -2,9 +2,9 @@ // Created by henri on 16.10.23. // #include "idol/modeling//expressions/operations/operators.h" -#include "idol/modeling//solutions/Solution.h" +#include "idol/modeling//solutions/Point.h" -double idol::evaluate(const Expr& t_expr, const Solution::Primal& t_values) { +double idol::evaluate(const Expr& t_expr, const PrimalPoint& t_values) { const auto& as_numerical = [](const Constant& t_constant) { diff --git a/lib/src/modeling/matrix/Row.cpp b/lib/src/modeling/matrix/Row.cpp index f5fe68fe..c76812f5 100644 --- a/lib/src/modeling/matrix/Row.cpp +++ b/lib/src/modeling/matrix/Row.cpp @@ -3,13 +3,13 @@ // #include "idol/modeling/matrix/Row.h" #include "idol/modeling/expressions/operations/operators.h" -#include "idol/modeling/solutions/Solution.h" +#include "idol/modeling/solutions/Point.h" #include const idol::Row idol::Row::EmptyRow; -double idol::Row::value(const idol::Solution::Primal &t_primals) const { +double idol::Row::value(const idol::PrimalPoint &t_primals) const { double result = -rhs(); @@ -24,7 +24,7 @@ double idol::Row::value(const idol::Solution::Primal &t_primals) const { return result; } -bool idol::Row::is_violated(const idol::Solution::Primal &t_primals, idol::CtrType t_type, double t_tolerance) const { +bool idol::Row::is_violated(const idol::PrimalPoint &t_primals, idol::CtrType t_type, double t_tolerance) const { const double value = this->value(t_primals); diff --git a/lib/src/optimizers/mixed-integer-optimization/callbacks/Callback.cpp b/lib/src/optimizers/mixed-integer-optimization/callbacks/Callback.cpp index b86d6f61..cb2c7662 100644 --- a/lib/src/optimizers/mixed-integer-optimization/callbacks/Callback.cpp +++ b/lib/src/optimizers/mixed-integer-optimization/callbacks/Callback.cpp @@ -20,7 +20,7 @@ void idol::Callback::throw_if_no_interface() const { } } -idol::Solution::Primal idol::Callback::primal_solution() const { +idol::PrimalPoint idol::Callback::primal_solution() const { throw_if_no_interface(); return m_interface->primal_solution(); } @@ -35,7 +35,7 @@ const idol::Model &idol::Callback::original_model() const { return m_interface->original_model(); } -void idol::Callback::submit_heuristic_solution(const idol::Solution::Primal &t_solution) { +void idol::Callback::submit_heuristic_solution(const idol::PrimalPoint &t_solution) { throw_if_no_interface(); m_interface->submit_heuristic_solution(t_solution); } diff --git a/lib/src/optimizers/mixed-integer-optimization/callbacks/CutSeparation.cpp b/lib/src/optimizers/mixed-integer-optimization/callbacks/CutSeparation.cpp index ae20788e..20122889 100644 --- a/lib/src/optimizers/mixed-integer-optimization/callbacks/CutSeparation.cpp +++ b/lib/src/optimizers/mixed-integer-optimization/callbacks/CutSeparation.cpp @@ -69,7 +69,7 @@ void idol::impl::CutSeparation::operator()(CallbackEvent t_event) { } std::pair, idol::ObjectiveSense> -idol::impl::CutSeparation::create_separation_objective(const idol::Solution::Primal &t_primal_solution) { +idol::impl::CutSeparation::create_separation_objective(const idol::PrimalPoint &t_primal_solution) { throw Exception("TODO: Was using Constant"); /* diff --git a/lib/src/optimizers/mixed-integer-optimization/dantzig-wolfe/Formulation.cpp b/lib/src/optimizers/mixed-integer-optimization/dantzig-wolfe/Formulation.cpp index 3411d421..d94b475d 100644 --- a/lib/src/optimizers/mixed-integer-optimization/dantzig-wolfe/Formulation.cpp +++ b/lib/src/optimizers/mixed-integer-optimization/dantzig-wolfe/Formulation.cpp @@ -317,7 +317,7 @@ void idol::DantzigWolfe::Formulation::add_aggregation_constraint(unsigned int t_ } void idol::DantzigWolfe::Formulation::generate_column(unsigned int t_sub_problem_id, - idol::Solution::Primal t_generator) { + idol::PrimalPoint t_generator) { throw Exception("TODO: Was using Constant"); /* @@ -336,8 +336,8 @@ void idol::DantzigWolfe::Formulation::generate_column(unsigned int t_sub_problem } double idol::DantzigWolfe::Formulation::compute_reduced_cost(unsigned int t_sub_problem_id, - const idol::Solution::Dual &t_master_dual, - const idol::Solution::Primal &t_generator) { + const idol::DualPoint &t_master_dual, + const idol::PrimalPoint &t_generator) { throw Exception("TODO: Was using Constant"); /* double result = 0.; @@ -368,7 +368,7 @@ double idol::DantzigWolfe::Formulation::compute_reduced_cost(unsigned int t_sub_ } void idol::DantzigWolfe::Formulation::update_sub_problem_objective(unsigned int t_sub_problem_id, - const idol::Solution::Dual &t_master_dual, + const idol::DualPoint &t_master_dual, bool t_use_farkas) { throw Exception("TODO: Was using Constant"); @@ -425,7 +425,7 @@ void idol::DantzigWolfe::Formulation::update_sub_problem_objective(unsigned int } double idol::DantzigWolfe::Formulation::get_original_space_var_primal(const idol::Var &t_var, - const idol::Solution::Primal &t_master_primal) const { + const idol::PrimalPoint &t_master_primal) const { const unsigned int sub_problem_id = t_var.get(m_decomposition_by_var); @@ -455,7 +455,7 @@ void idol::DantzigWolfe::Formulation::update_var_lb(const idol::Var &t_var, doub } if (t_remove_infeasible_columns) { - remove_column_if(sub_problem_id, [&](const Var &t_object, const Solution::Primal &t_generator) { + remove_column_if(sub_problem_id, [&](const Var &t_object, const PrimalPoint &t_generator) { return Row(t_var, t_lb).is_violated(t_generator, GreaterOrEqual, Tolerance::Feasibility); }); } @@ -479,7 +479,7 @@ void idol::DantzigWolfe::Formulation::update_var_ub(const idol::Var &t_var, doub } if (t_remove_infeasible_columns) { - remove_column_if(sub_problem_id, [&](const Var &t_object, const Solution::Primal &t_generator) { + remove_column_if(sub_problem_id, [&](const Var &t_object, const PrimalPoint &t_generator) { return Row(t_var, t_ub).is_violated(t_generator, LessOrEqual, Tolerance::Feasibility); }); } @@ -534,7 +534,7 @@ idol::LinExpr idol::DantzigWolfe::Formulation::reformulate_sub_proble } void idol::DantzigWolfe::Formulation::remove_column_if(unsigned int t_sub_problem_id, - const std::function &t_indicator_for_removal) { + const std::function &t_indicator_for_removal) { auto& present_generators = m_present_generators[t_sub_problem_id]; auto it = present_generators.begin(); @@ -661,7 +661,7 @@ void idol::DantzigWolfe::Formulation::add(const idol::Ctr &t_ctr, idol::CtrType if (sub_problem_id != MasterId) { - remove_column_if(sub_problem_id, [&](const Var& t_alpha, const Solution::Primal& t_generator) { + remove_column_if(sub_problem_id, [&](const Var& t_alpha, const PrimalPoint& t_generator) { return t_row.is_violated(t_generator, t_type); }); @@ -756,7 +756,7 @@ void idol::DantzigWolfe::Formulation::load_columns_from_pool() { } bool -idol::DantzigWolfe::Formulation::is_feasible(const idol::Solution::Primal &t_primal, unsigned int t_sub_problem_id) { +idol::DantzigWolfe::Formulation::is_feasible(const idol::PrimalPoint &t_primal, unsigned int t_sub_problem_id) { const auto& model = m_sub_problems[t_sub_problem_id]; diff --git a/lib/src/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/ArtificialCosts.cpp b/lib/src/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/ArtificialCosts.cpp index f2ea5fad..17aeef5b 100644 --- a/lib/src/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/ArtificialCosts.cpp +++ b/lib/src/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/ArtificialCosts.cpp @@ -83,7 +83,7 @@ void idol::DantzigWolfe::ArtificialCosts::Strategy::find_initial_columns(idol::O current_costs *= m_update_factor; } - update_objective_function(formulation, Solution::Primal(), false); + update_objective_function(formulation, PrimalPoint(), false); t_column_generation.execute(); @@ -154,7 +154,7 @@ void idol::DantzigWolfe::ArtificialCosts::Strategy::delete_artificial_variables( } -bool idol::DantzigWolfe::ArtificialCosts::Strategy::all_artificial_variables_are_non_basic(const Solution::Primal &t_primal_values) const { +bool idol::DantzigWolfe::ArtificialCosts::Strategy::all_artificial_variables_are_non_basic(const PrimalPoint &t_primal_values) const { for (const auto& var : m_artificial_variables) { if (!equals(t_primal_values.get(var), 0., Tolerance::Feasibility)) { @@ -171,7 +171,7 @@ void idol::DantzigWolfe::ArtificialCosts::Strategy::restore_objective_function(D void idol::DantzigWolfe::ArtificialCosts::Strategy::update_objective_function( DantzigWolfe::Formulation& t_formulation, - const Solution::Primal& t_primal_values, + const PrimalPoint& t_primal_values, bool t_include_original_objective_function) { if (!t_include_original_objective_function) { diff --git a/lib/src/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/DantzigWolfeInfeasibilityStrategy.cpp b/lib/src/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/DantzigWolfeInfeasibilityStrategy.cpp index 09244b20..847a4d57 100644 --- a/lib/src/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/DantzigWolfeInfeasibilityStrategy.cpp +++ b/lib/src/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/DantzigWolfeInfeasibilityStrategy.cpp @@ -3,7 +3,7 @@ // #include "idol/optimizers/mixed-integer-optimization/dantzig-wolfe/infeasibility-strategies/DantzigWolfeInfeasibilityStrategy.h" -const idol::Solution::Primal &idol::DantzigWolfe::InfeasibilityStrategyFactory::Strategy::primal_solution() const { +const idol::PrimalPoint &idol::DantzigWolfe::InfeasibilityStrategyFactory::Strategy::primal_solution() const { if (!m_primal_solution.has_value()) { throw Exception("Primal value not accessible."); diff --git a/lib/src/optimizers/mixed-integer-optimization/padm/Formulation.cpp b/lib/src/optimizers/mixed-integer-optimization/padm/Formulation.cpp index 85d7c345..8fd8b3da 100644 --- a/lib/src/optimizers/mixed-integer-optimization/padm/Formulation.cpp +++ b/lib/src/optimizers/mixed-integer-optimization/padm/Formulation.cpp @@ -256,7 +256,7 @@ idol::ADM::Formulation::dispatch_obj(const Model &t_src_model, unsigned int t_su } void idol::ADM::Formulation::fix_sub_problem(unsigned int t_sub_problem_id, - const std::vector &t_primals) { + const std::vector &t_primals) { // Constraints for (const auto& [ctr, pattern] : m_constraint_patterns[t_sub_problem_id]) { @@ -293,7 +293,7 @@ void idol::ADM::Formulation::fix_sub_problem(unsigned int t_sub_problem_id, } double idol::ADM::Formulation::fix(const idol::Constant &t_constant, - const std::vector &t_primals) { + const std::vector &t_primals) { double result = t_constant.numerical(); for (const auto& [param, coefficient] : t_constant.linear()) { @@ -325,7 +325,7 @@ const idol::Model &idol::ADM::Formulation::sub_problem(const idol::Var &t_var) c } bool -idol::ADM::Formulation::update_penalty_parameters(const std::vector &t_primals, +idol::ADM::Formulation::update_penalty_parameters(const std::vector &t_primals, PenaltyUpdate& t_penalty_update) { const unsigned int n_sub_problems = m_sub_problems.size(); @@ -417,7 +417,7 @@ void idol::ADM::Formulation::initialize_penalty_parameters(double t_value) { } -void idol::ADM::Formulation::update_penalty_parameters_independently(const std::vector &t_primals, +void idol::ADM::Formulation::update_penalty_parameters_independently(const std::vector &t_primals, idol::PenaltyUpdate &t_penalty_update) { for (unsigned int i = 0, n_sub_problems = m_sub_problems.size() ; i < n_sub_problems ; ++i) { diff --git a/lib/src/optimizers/mixed-integer-optimization/padm/Optimizers_PADM.cpp b/lib/src/optimizers/mixed-integer-optimization/padm/Optimizers_PADM.cpp index 5041a772..0def49ae 100644 --- a/lib/src/optimizers/mixed-integer-optimization/padm/Optimizers_PADM.cpp +++ b/lib/src/optimizers/mixed-integer-optimization/padm/Optimizers_PADM.cpp @@ -3,6 +3,7 @@ // #include "idol/optimizers/mixed-integer-optimization/padm/Optimizers_PADM.h" +#include "idol/optimizers/logs.h" #include #include @@ -202,7 +203,7 @@ void idol::Optimizers::PADM::hook_before_optimize() { m_last_iteration_with_no_feasibility_change.reset(); m_last_objective_value_when_rescaled.reset(); m_current_initial_penalty_parameter = m_initial_penalty_parameter; - m_last_solutions = std::vector(n_sub_problems); + m_last_solutions = std::vector(n_sub_problems); for (unsigned int i = 0 ; i < n_sub_problems ; ++i) { @@ -395,7 +396,7 @@ idol::Optimizers::PADM::solve_sub_problem(unsigned int t_sub_problem_id) { const auto& reason = model.get_reason(); - Solution::Primal sub_problem_solution; + PrimalPoint sub_problem_solution; sub_problem_solution.set_status(status); sub_problem_solution.set_reason(reason); m_last_solutions[t_sub_problem_id] = std::move(sub_problem_solution); @@ -456,7 +457,7 @@ void idol::Optimizers::PADM::log_inner_loop(unsigned int t_inner_loop_iteration) std::cout << std::endl; } -double idol::Optimizers::PADM::infeasibility_linf(unsigned int t_sub_problem_id, const Solution::Primal& t_solution) const { +double idol::Optimizers::PADM::infeasibility_linf(unsigned int t_sub_problem_id, const PrimalPoint& t_solution) const { double result = 0; @@ -468,7 +469,7 @@ double idol::Optimizers::PADM::infeasibility_linf(unsigned int t_sub_problem_id, return result; } -double idol::Optimizers::PADM::infeasibility_l1(unsigned int t_sub_problem_id, const Solution::Primal& t_solution) const { +double idol::Optimizers::PADM::infeasibility_l1(unsigned int t_sub_problem_id, const PrimalPoint& t_solution) const { double result = 0; diff --git a/lib/src/optimizers/mixed-integer-optimization/padm/SubProblem.cpp b/lib/src/optimizers/mixed-integer-optimization/padm/SubProblem.cpp index 325812dd..73b7db75 100644 --- a/lib/src/optimizers/mixed-integer-optimization/padm/SubProblem.cpp +++ b/lib/src/optimizers/mixed-integer-optimization/padm/SubProblem.cpp @@ -29,7 +29,7 @@ const idol::OptimizerFactory &idol::ADM::SubProblem::optimizer_factory() const { return *m_optimizer_factory; } -idol::ADM::SubProblem &idol::ADM::SubProblem::with_initial_point(const Solution::Primal &t_initial_point) { +idol::ADM::SubProblem &idol::ADM::SubProblem::with_initial_point(const PrimalPoint &t_initial_point) { if (m_initial_point) { throw Exception("The initial point has already been set."); @@ -40,6 +40,6 @@ idol::ADM::SubProblem &idol::ADM::SubProblem::with_initial_point(const Solution: return *this; } -idol::Solution::Primal idol::ADM::SubProblem::initial_point() const { - return m_initial_point.has_value() ? *m_initial_point : Solution::Primal(); +idol::PrimalPoint idol::ADM::SubProblem::initial_point() const { + return m_initial_point.has_value() ? *m_initial_point : PrimalPoint(); } diff --git a/lib/src/optimizers/mixed-integer-optimization/wrappers/GLPK/Optimizers_GLPK.cpp b/lib/src/optimizers/mixed-integer-optimization/wrappers/GLPK/Optimizers_GLPK.cpp index 6f0d74ae..a58704ab 100644 --- a/lib/src/optimizers/mixed-integer-optimization/wrappers/GLPK/Optimizers_GLPK.cpp +++ b/lib/src/optimizers/mixed-integer-optimization/wrappers/GLPK/Optimizers_GLPK.cpp @@ -418,7 +418,7 @@ void idol::Optimizers::GLPK::compute_farkas_certificate() { glp_simplex(m_model, &m_simplex_parameters); // Save dual values as Farkas certificate - m_farkas_certificate = Solution::Dual(); + m_farkas_certificate = DualPoint(); double objective_value = model.get_obj_expr().constant(); for (const auto& ctr : model.ctrs()) { const double dual = glp_get_row_dual(m_model, lazy(ctr).impl()); @@ -518,7 +518,7 @@ void idol::Optimizers::GLPK::compute_unbounded_ray() { glp_simplex(m_model, &m_simplex_parameters); // Save ray - m_unbounded_ray = Solution::Primal(); + m_unbounded_ray = PrimalPoint(); const double objective_value = model.get_obj_expr().constant() + glp_get_obj_val(m_model); m_unbounded_ray->set_objective_value(objective_value); for (const auto& var : model.vars()) { diff --git a/lib/src/optimizers/mixed-integer-optimization/wrappers/Gurobi/GurobiCallbackI.cpp b/lib/src/optimizers/mixed-integer-optimization/wrappers/Gurobi/GurobiCallbackI.cpp index 7e7a09a8..5e2f3b6f 100644 --- a/lib/src/optimizers/mixed-integer-optimization/wrappers/Gurobi/GurobiCallbackI.cpp +++ b/lib/src/optimizers/mixed-integer-optimization/wrappers/Gurobi/GurobiCallbackI.cpp @@ -70,11 +70,11 @@ GRBTempConstr idol::GurobiCallbackI::gurobi_temp_constr(const TempCtr &t_temp_ct throw Exception("Unexpected constraint type."); } -idol::Solution::Primal idol::GurobiCallbackI::primal_solution() const { +idol::PrimalPoint idol::GurobiCallbackI::primal_solution() const { auto* me = const_cast(this); - Solution::Primal result; + PrimalPoint result; if (where == GRB_CB_MIPSOL) { @@ -126,7 +126,7 @@ const idol::Model &idol::GurobiCallbackI::original_model() const { return m_parent.parent(); } -void idol::GurobiCallbackI::submit_heuristic_solution(idol::Solution::Primal t_solution) { +void idol::GurobiCallbackI::submit_heuristic_solution(idol::PrimalPoint t_solution) { unsigned int size = t_solution.size(); diff --git a/lib/src/optimizers/mixed-integer-optimization/wrappers/Mosek/MosekCallbackI.cpp b/lib/src/optimizers/mixed-integer-optimization/wrappers/Mosek/MosekCallbackI.cpp index 780569a0..88176c85 100644 --- a/lib/src/optimizers/mixed-integer-optimization/wrappers/Mosek/MosekCallbackI.cpp +++ b/lib/src/optimizers/mixed-integer-optimization/wrappers/Mosek/MosekCallbackI.cpp @@ -67,11 +67,11 @@ void idol::MosekCallbackI::add_lazy_cut(const idol::TempCtr &t_cut) { throw Exception("Mosek does not support lazy cuts."); } -void idol::MosekCallbackI::submit_heuristic_solution(idol::Solution::Primal t_solution) { +void idol::MosekCallbackI::submit_heuristic_solution(idol::PrimalPoint t_solution) { throw Exception("Mosek does not support heuristic solutions."); } -idol::Solution::Primal idol::MosekCallbackI::primal_solution() const { +idol::PrimalPoint idol::MosekCallbackI::primal_solution() const { throw Exception("Mosek does not support accessing primal solutions in callback."); }