diff --git a/dev/main.cpp b/dev/main.cpp index 27bcf49f..6698d799 100644 --- a/dev/main.cpp +++ b/dev/main.cpp @@ -19,6 +19,7 @@ #include "idol/mixed-integer/optimizers/branch-and-bound/BranchAndBound.h" #include "idol/mixed-integer/modeling/expressions/QuadExpr.h" #include "idol/general/utils/GenerationPattern.h" +#include "idol/mixed-integer/modeling/models/Dualizer.h" using namespace idol; @@ -29,16 +30,13 @@ int main(int t_argc, const char** t_argv) { const auto x = model.add_vars(Dim<1>(10), 0, 1, Binary, 1, "x"); - Point point; - point.set(x[0], 5); + Dualizer dualizer(model); - GenerationPattern pattern; - pattern.constant() += 2 + 2 * x[0]; + auto s = idol_Sum(i, Range(2), i); - pattern.linear().set(x[1], x[0]); - pattern.linear().set(x[2], 10 * x[0] + 4); + auto sum = idol_Sum(i, Range(0), x[i]); - std::cout << pattern(point) << std::endl; + std::cout << sum << std::endl; return 0; } diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 53376210..954613af 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -227,6 +227,8 @@ add_library(idol STATIC src/mixed-integer/modeling/constraints/QCtrVersion.cpp src/mixed-integer/modeling/constraints/QCtr.cpp include/idol/general/utils/GenerationPattern.h + include/idol/mixed-integer/modeling/models/Dualizer.h + src/mixed-integer/modeling/models/Dualizer.cpp ) find_package(OpenMP REQUIRED) diff --git a/lib/include/idol/general/utils/Map.h b/lib/include/idol/general/utils/Map.h index 431f4cc4..ca3a1bc9 100644 --- a/lib/include/idol/general/utils/Map.h +++ b/lib/include/idol/general/utils/Map.h @@ -83,13 +83,13 @@ namespace idol { namespace idol { template< - class Key, + class KeyT, class T, - class Hash = impl::hash, - class KeyEqual = std::equal_to, - class Allocator = std::allocator > + class Hash = impl::hash, + class KeyEqual = std::equal_to, + class Allocator = std::allocator > > - using Map = std::unordered_map; + using Map = std::unordered_map; } diff --git a/lib/include/idol/mixed-integer/modeling/expressions/AffExpr.h b/lib/include/idol/mixed-integer/modeling/expressions/AffExpr.h index af45f405..b1ea645a 100644 --- a/lib/include/idol/mixed-integer/modeling/expressions/AffExpr.h +++ b/lib/include/idol/mixed-integer/modeling/expressions/AffExpr.h @@ -11,21 +11,19 @@ namespace idol { class Var; - template + template class AffExpr; } -template +template class idol::AffExpr { - LinExpr m_linear; + LinExpr m_linear; double m_constant = 0.; public: AffExpr(); - AffExpr(const ValueT& t_constant); // NOLINT(google-explicit-constructor) - AffExpr(ValueT&& t_constant); // NOLINT(google-explicit-constructor) - AffExpr(const Key1& t_var); // NOLINT(google-explicit-constructor) - AffExpr(LinExpr&& t_expr); // NOLINT(google-explicit-constructor) - AffExpr(const LinExpr& t_expr); // NOLINT(google-explicit-constructor) + AffExpr(ValueT t_constant); // NOLINT(google-explicit-constructor) + AffExpr(const KeyT& t_key); // NOLINT(google-explicit-constructor) + AffExpr(LinExpr t_expr); // NOLINT(google-explicit-constructor) virtual ~AffExpr() = default; @@ -36,13 +34,14 @@ class idol::AffExpr { AffExpr& operator=(AffExpr&&) noexcept = default; AffExpr& operator+=(const AffExpr& t_rhs); + AffExpr& operator-=(const AffExpr& t_rhs); AffExpr& operator*=(double t_rhs); AffExpr& operator/=(double t_rhs); AffExpr operator-() const; - LinExpr& linear() { return m_linear; } - [[nodiscard]] const LinExpr& linear() const { return m_linear; } + LinExpr& linear() { return m_linear; } + [[nodiscard]] const LinExpr& linear() const { return m_linear; } double& constant() { return m_constant; } @@ -56,6 +55,11 @@ class idol::AffExpr { } }; +template +idol::AffExpr::AffExpr(const KeyT &t_key) : m_linear(t_key) { + +} + template idol::AffExpr idol::AffExpr::operator-() const { auto result = *this; @@ -70,27 +74,12 @@ idol::AffExpr::AffExpr() { } template -idol::AffExpr::AffExpr(const ValueT& t_constant) : m_constant(t_constant) { - -} - -template -idol::AffExpr::AffExpr(ValueT&& t_constant) : m_constant(t_constant) { - -} - -template -idol::AffExpr::AffExpr(const Key1 &t_var) : m_linear(t_var) { - -} - -template -idol::AffExpr::AffExpr(LinExpr &&t_expr) : m_linear(std::move(t_expr)) { +idol::AffExpr::AffExpr(ValueT t_constant) : m_constant(std::move(t_constant)) { } template -idol::AffExpr::AffExpr(const LinExpr &t_expr) : m_linear(t_expr) { +idol::AffExpr::AffExpr(LinExpr t_expr) : m_linear(std::move(t_expr)) { } diff --git a/lib/include/idol/mixed-integer/modeling/expressions/LinExpr.h b/lib/include/idol/mixed-integer/modeling/expressions/LinExpr.h index c2ff0c24..4dabefbb 100644 --- a/lib/include/idol/mixed-integer/modeling/expressions/LinExpr.h +++ b/lib/include/idol/mixed-integer/modeling/expressions/LinExpr.h @@ -22,25 +22,61 @@ namespace idol { } /** - * @tparam Key the class representing keys + * @tparam KeyT the class representing keys */ -template -class idol::LinExpr : public SparseVector { +template +class idol::LinExpr : public SparseVector { public: LinExpr() = default; - LinExpr(SparseVector&& t_vector) : SparseVector(std::move(t_vector)) {} - LinExpr(const Key& t_key); // NOLINT(google-explicit-constructor) - LinExpr(const ValueT& t_factor, const Key& t_key); - LinExpr(ValueT&& t_factor, const Key& t_key); + LinExpr(KeyT t_key); // NOLINT(google-explicit-constructor) + LinExpr(SparseVector t_vector) : SparseVector(std::move(t_vector)) {} // NOLINT(*-explicit-constructor) + LinExpr(const ValueT& t_factor, const KeyT& t_key); + LinExpr(ValueT&& t_factor, const KeyT& t_key); + + LinExpr(const LinExpr&) = default; + LinExpr(LinExpr&&) = default; + + LinExpr& operator=(const LinExpr&) noexcept = default; + LinExpr& operator=(LinExpr&&) noexcept = default; + + LinExpr& operator+=(const LinExpr& t_rhs); + LinExpr& operator+=(const KeyT& t_rhs); + + LinExpr& operator-=(const LinExpr& t_rhs); + LinExpr& operator-=(const KeyT& t_rhs); }; +template +idol::LinExpr &idol::LinExpr::operator-=(const KeyT &t_rhs) { + SparseVector::operator-=(SparseVector(t_rhs, 1)); + return *this; +} + +template +idol::LinExpr &idol::LinExpr::operator-=(const idol::LinExpr &t_rhs) { + SparseVector::operator-=((SparseVector&) t_rhs); + return *this; +} + +template +idol::LinExpr &idol::LinExpr::operator+=(const KeyT &t_rhs) { + SparseVector::operator+=(SparseVector(t_rhs, 1)); + return *this; +} + +template +idol::LinExpr& idol::LinExpr::operator+=(const idol::LinExpr &t_rhs) { + SparseVector::operator+=((SparseVector&) t_rhs); + return *this; +} + template idol::LinExpr::LinExpr(ValueT &&t_factor, const Key &t_key) : SparseVector(t_key, std::move(t_factor)) { } template -idol::LinExpr::LinExpr(const Key &t_key) : SparseVector(t_key, 1.) { +idol::LinExpr::LinExpr(Key t_key) : SparseVector(t_key, 1.) { } diff --git a/lib/include/idol/mixed-integer/modeling/expressions/QuadExpr.h b/lib/include/idol/mixed-integer/modeling/expressions/QuadExpr.h index 4f22ff1d..e02ab2b2 100644 --- a/lib/include/idol/mixed-integer/modeling/expressions/QuadExpr.h +++ b/lib/include/idol/mixed-integer/modeling/expressions/QuadExpr.h @@ -17,14 +17,11 @@ class idol::QuadExpr : public LinExpr, ValueT> { AffExpr m_affine; public: QuadExpr() = default; - QuadExpr(const KeyT& t_key) : m_affine(t_key) {} - QuadExpr(KeyT&& t_key) : m_affine(std::move(t_key)) {} - QuadExpr(const ValueT& t_value) : m_affine(t_value) {} - QuadExpr(ValueT&& t_value) : m_affine(std::move(t_value)) {} - QuadExpr(const LinExpr& t_expr) : m_affine(t_expr) {} // NOLINT(*-explicit-constructor) - QuadExpr(LinExpr&& t_expr) : m_affine(std::move(t_expr)) {} // NOLINT(*-explicit-constructor) - QuadExpr(const AffExpr& t_expr) : m_affine(t_expr) {} // NOLINT(*-explicit-constructor) - QuadExpr(AffExpr&& t_expr) : m_affine(std::move(t_expr)) {} // NOLINT(*-explicit-constructor) + QuadExpr(ValueT t_constant) : m_affine(std::move(t_constant)) {} // NOLINT(*-explicit-constructor) + QuadExpr(const KeyT& t_key) : m_affine(std::move(t_key)) {} // NOLINT(*-explicit-constructor) + QuadExpr(LinExpr t_expr) : m_affine(std::move(t_expr)) {} // NOLINT(*-explicit-constructor) + QuadExpr(AffExpr t_expr) : m_affine(std::move(t_expr)) {} // NOLINT(*-explicit-constructor) + QuadExpr(const KeyT& t_key1, const KeyT& t_key2) : LinExpr, ValueT>(CommutativePair(t_key1, t_key2)) {} QuadExpr(const ValueT& t_factor, const KeyT& t_key1, const KeyT& t_key2) : LinExpr, ValueT>(CommutativePair(t_key1, t_key2), t_factor) {} QuadExpr(ValueT&& t_factor, const KeyT& t_key1, const KeyT& t_key2) : LinExpr, ValueT>(CommutativePair(t_key1, t_key2), std::move(t_factor)) {} @@ -46,11 +43,11 @@ class idol::QuadExpr : public LinExpr, ValueT> { AffExpr& affine() { return m_affine; } const AffExpr& affine() const { return m_affine; } - bool has_quadratic() const { return !LinExpr, ValueT>::empty(); } + [[nodiscard]] bool has_quadratic() const { return !LinExpr, ValueT>::empty(); } - bool empty_all() const { return LinExpr, ValueT>::empty() && m_affine.linear().empty(); } + [[nodiscard]] bool empty_all() const { return LinExpr, ValueT>::empty() && m_affine.linear().empty(); } - bool is_zero(double t_tolerance) const override; + [[nodiscard]] bool is_zero(double t_tolerance) const override; void clear_all(); }; diff --git a/lib/include/idol/mixed-integer/modeling/expressions/operations/operators.h b/lib/include/idol/mixed-integer/modeling/expressions/operations/operators.h index 83082fa3..1109528c 100644 --- a/lib/include/idol/mixed-integer/modeling/expressions/operations/operators.h +++ b/lib/include/idol/mixed-integer/modeling/expressions/operations/operators.h @@ -8,6 +8,8 @@ #include "operators_utils.h" #include "idol/general/utils/Point.h" #include +#include +#include namespace idol { template @@ -47,821 +49,89 @@ namespace idol { return result; } - // Products - - // LinExpr - template - LinExpr operator*(double t_num, const KeyT& t_obj) { - return { t_num, t_obj }; - } - - template - LinExpr operator*(const KeyT& t_obj, double t_num) { - return { t_num, t_obj }; - } - - template - LinExpr operator*(double t_num, LinExpr&& t_lin_expr) { - LinExpr result(std::move(t_lin_expr)); - result *= t_num; - return result; - } - - template - LinExpr operator*(LinExpr&& t_lin_expr, double t_num) { - LinExpr result(std::move(t_lin_expr)); - result *= t_num; - return result; - } - - template - LinExpr operator*(double t_num, const LinExpr& t_lin_expr) { - LinExpr result(t_lin_expr); - result *= t_num; - return result; - } - - template - LinExpr operator*(const LinExpr& t_lin_expr, double t_num) { - LinExpr result(t_lin_expr); - result *= t_num; - return result; - } - - // AffExpr - - template - AffExpr operator*(double t_num, AffExpr&& t_expr) { - AffExpr result(std::move(t_expr)); - result *= t_num; - return result; - } - - template - AffExpr operator*(double t_num, const AffExpr& t_expr) { - AffExpr result(t_expr); - result *= t_num; - return result; - } - - template - AffExpr operator*(AffExpr&& t_expr, double t_num) { - AffExpr result(std::move(t_expr)); - result *= t_num; - return result; - } - - template - AffExpr operator*(const AffExpr& t_expr, double t_num) { - AffExpr result(t_expr); - result *= t_num; - return result; - } - - // QuadExpr - - template - QuadExpr operator*(const T& t_obj1, const T& t_obj2) { - return { t_obj1, t_obj2 }; - } - - template - QuadExpr operator*(double t_num, QuadExpr&& t_expr) { - QuadExpr result(std::move(t_expr)); - result *= t_num; - return result; - } - - template - QuadExpr operator*(double t_num, const QuadExpr& t_expr) { - QuadExpr result(t_expr); - result *= t_num; - return result; - } - - template - QuadExpr operator*(QuadExpr&& t_expr, double t_num) { - QuadExpr result(std::move(t_expr)); - result *= t_num; - return result; - } - - template - QuadExpr operator*(const QuadExpr& t_expr, double t_num) { - QuadExpr result(t_expr); - result *= t_num; - return result; - } - - template - QuadExpr operator*(const LinExpr& t_lin_expr, const LinExpr& t_lin_expr2) { - QuadExpr result; - for (const auto& [key, value] : t_lin_expr) { - result += value * t_lin_expr2 * key; - } - return result; - } - - // Addition - - // LinExpr - - template - LinExpr operator+(const KeyT& t_obj) { - return { t_obj }; - } - - template - LinExpr operator+(LinExpr&& t_lin_expr) { - return std::move(t_lin_expr); - } - - template - LinExpr operator+(const LinExpr& t_lin_expr) { - return t_lin_expr; - } - - template - LinExpr operator+(const KeyT& t_a, const KeyT& t_b) { - LinExpr result(t_a); - result += LinExpr(t_b); - return result; - } - - template - LinExpr operator+(LinExpr&& t_a, const LinExpr& t_b) { - LinExpr result(std::move(t_a)); - result += t_b; - return result; - } - - template - LinExpr operator+(const LinExpr& t_a, const LinExpr& t_b) { - LinExpr result(t_a); - result += t_b; - return result; - } - - template - LinExpr operator+(LinExpr&& t_a, const KeyT& t_b) { - LinExpr result(std::move(t_a)); - result += LinExpr(t_b); - return result; - } - - template - LinExpr operator+(const KeyT& t_a, LinExpr&& t_b) { - LinExpr result(t_a); - result += std::move(t_b); - return result; - } - - template - LinExpr operator+(const KeyT& t_a, const LinExpr& t_b) { - LinExpr result(t_a); - result += t_b; - return result; - } - - template - LinExpr operator+(const LinExpr& t_a, const KeyT& t_b) { - LinExpr result(t_a); - result += LinExpr(t_b); - return result; - } - - // AffExpr - - template - AffExpr operator+(const AffExpr&& t_expr) { - return std::move(t_expr); - } - - template - AffExpr operator+(const AffExpr& t_expr) { - return t_expr; - } - - template - AffExpr operator+(double t_term, LinExpr&& t_lin_expr) { - AffExpr result(std::move(t_lin_expr)); - result.constant() += t_term; - return result; - } - - template - AffExpr operator+(LinExpr&& t_lin_expr, double t_term) { - AffExpr result(std::move(t_lin_expr)); - result.constant() += t_term; - return result; - } - - template - AffExpr operator+(const LinExpr& t_lin_expr, double t_term) { - AffExpr result(t_lin_expr); - result.constant() += t_term; - return result; - } - - template - AffExpr operator+(double t_term, const LinExpr& t_lin_expr) { - AffExpr result(t_lin_expr); - result.constant() += t_term; - return result; - } - - template - AffExpr operator+(const AffExpr& t_a, AffExpr&& t_b) { - AffExpr result(std::move(t_b)); - result.linear() += t_a; - return result; - } - - template - AffExpr operator+(double t_num, AffExpr&& t_expr) { - AffExpr result(std::move(t_expr)); - result.constant() += t_num; - return result; - } - - template - AffExpr operator+(AffExpr&& t_expr, double t_num) { - AffExpr result(std::move(t_expr)); - result.constant() += t_num; - return result; - } - - template - AffExpr operator+(const AffExpr& t_expr, double t_num) { - AffExpr result(t_expr); - result.constant() += t_num; - return result; - } - - template - AffExpr operator+(double t_num, const AffExpr& t_expr) { - AffExpr result(t_expr); - result.constant() += t_num; - return result; - } - - template - AffExpr operator+(AffExpr&& t_a, const KeyT& t_b) { - AffExpr result(std::move(t_a)); - result.linear() += t_b; - return result; - } - - template - AffExpr operator+(const KeyT& t_a, AffExpr&& t_b) { - AffExpr result(std::move(t_b)); - result.linear() += t_a; - return result; - } - - template - AffExpr operator+(const KeyT& t_a, const AffExpr& t_b) { - AffExpr result(t_b); - result.linear() += t_a; - return result; - } - - template - AffExpr operator+(const AffExpr& t_a, const KeyT& t_b) { - AffExpr result(t_a); - result.linear() += t_b; - return result; - } - - template - AffExpr operator+(const AffExpr& t_a, LinExpr&& t_b) { - AffExpr result(t_a); - result += std::move(t_b); - return result; - } - - template - AffExpr operator+(LinExpr&& t_a, const AffExpr& t_b) { - AffExpr result(std::move(t_a)); - result += t_b; - return result; - } - - template - AffExpr operator+(const LinExpr& t_a, AffExpr&& t_b) { - AffExpr result(std::move(t_b)); - result += t_a; - return result; - } - - template - AffExpr operator+(AffExpr&& t_a, const LinExpr& t_b) { - AffExpr result(std::move(t_a)); - result += t_b; - return result; - } - - template - AffExpr operator+(AffExpr&& t_a, LinExpr&& t_b) { - AffExpr result(std::move(t_a)); - result += std::move(t_b); - return result; - } - - template - AffExpr operator+(LinExpr&& t_a, AffExpr&& t_b) { - AffExpr result(std::move(t_a)); - result += std::move(t_b); - return result; - } - - template - AffExpr operator+(const AffExpr& t_a, const LinExpr& t_b) { - AffExpr result(t_a); - result += t_b; - return result; - } - - template - AffExpr operator+(const LinExpr& t_a, const AffExpr& t_b) { - AffExpr result(t_b); - result += t_a; - return result; - } - - template - AffExpr operator+(AffExpr&& t_a, AffExpr&& t_b) { - AffExpr result(std::move(t_a)); - result += std::move(t_b); - return result; - } - - template - AffExpr operator+(const AffExpr& t_a, const AffExpr& t_b) { - AffExpr result(t_a); - result += t_b; - return result; - } - - // QuadExpr - - template - QuadExpr operator+(QuadExpr&& t_expr) { - return std::move(t_expr); - } - - template - QuadExpr operator+(const QuadExpr& t_expr) { - return t_expr; - } - - template - QuadExpr operator+(AffExpr&& t_a, const QuadExpr& t_b) { - QuadExpr result(std::move(t_a)); - result += t_b; - return result; - } - - template - QuadExpr operator+(const QuadExpr& t_a, AffExpr&& t_b) { - QuadExpr result(std::move(t_b)); - result += t_a; - return result; - } - - template - QuadExpr operator+(const AffExpr& t_a, QuadExpr&& t_b) { - QuadExpr result(std::move(t_b)); - result += t_a; - return result; - } - - template - QuadExpr operator+(AffExpr&& t_a, QuadExpr&& t_b) { - QuadExpr result(std::move(t_b)); - result += std::move(t_a); - return result; - } - - template - QuadExpr operator+(QuadExpr&& t_a, const AffExpr& t_b) { - QuadExpr result(std::move(t_a)); - result += t_b; - return result; - } - - template - QuadExpr operator+(const QuadExpr& t_a, const AffExpr& t_b) { - QuadExpr result(t_a); - result += t_b; - return result; - } - - template - QuadExpr operator+(const AffExpr& t_a, const QuadExpr& t_b) { - QuadExpr result(t_b); - result += t_a; - return result; - } - - template - QuadExpr operator+(QuadExpr&& t_a, const QuadExpr& t_b) { - QuadExpr result(std::move(t_a)); - result += t_b; - return result; - } - - template - QuadExpr operator+(const QuadExpr& t_a, QuadExpr&& t_b) { - QuadExpr result(std::move(t_b)); - result += t_a; - return result; - } - - template - QuadExpr operator+(const QuadExpr& t_a, const QuadExpr& t_b) { - QuadExpr result(t_a); - result += t_b; - return result; - } - - template - QuadExpr operator+(const KeyT& t_a, QuadExpr&& t_b) { - QuadExpr result(std::move(t_b)); - result += LinExpr(t_a); - return result; - } - - template - QuadExpr operator+(QuadExpr&& t_b, const KeyT& t_a) { - QuadExpr result(std::move(t_b)); - result += LinExpr(t_a); - return result; - } - - template - QuadExpr operator+(const KeyT& t_a, const QuadExpr& t_b) { - QuadExpr result(t_b); - result += LinExpr(t_a); - return result; - } - - template - QuadExpr operator+(const QuadExpr& t_b, const KeyT& t_a) { - QuadExpr result(t_b); - result += LinExpr(t_a); - return result; - } - - // Subtraction - - // LinExpr - - template - LinExpr operator-(const KeyT& t_key) { - return { -1, t_key}; - } - - template - LinExpr operator-(const LinExpr& t_lin_expr) { - LinExpr result; - result -= t_lin_expr; - return result; - } - - template - LinExpr operator-(const KeyT& t_a, const KeyT& t_b) { - LinExpr result(t_a); - result -= LinExpr(t_b); - return result; - } - - template - LinExpr operator-(LinExpr&& t_a, const KeyT& t_b) { - LinExpr result(std::move(t_a)); - result -= LinExpr(t_b); - return result; - } - - template - LinExpr operator-(const KeyT& t_a, LinExpr&& t_b) { - LinExpr result(t_a); - result -= std::move(t_b); - return result; - } - - template - LinExpr operator-(const LinExpr& t_a, const KeyT& t_b) { - LinExpr result(t_a); - result -= LinExpr(t_b); - return result; - } - - template - LinExpr operator-(const KeyT& t_a, const LinExpr& t_b) { - LinExpr result(t_a); - result -= t_b; - return result; - } - - template - LinExpr operator-(LinExpr&& t_a, const LinExpr& t_b) { - LinExpr result(std::move(t_a)); - result -= LinExpr(t_b); - return result; - } - - template - LinExpr operator-(const LinExpr& t_a, LinExpr&& t_b) { - LinExpr result(t_a); - result -= std::move(t_b); - return result; - } - - template - LinExpr operator-(LinExpr&& t_a, LinExpr&& t_b) { - LinExpr result(std::move(t_a)); - result -= std::move(t_b); - return result; - } - - template - LinExpr operator-(const LinExpr& t_a, const LinExpr& t_b) { - LinExpr result(t_a); - result -= t_b; - return result; - } - - // AffExpr - - template - AffExpr operator-(AffExpr&& t_a, double t_b) { - AffExpr result(std::move(t_a)); - result.constant() -= t_b; - return result; - } - - template - AffExpr operator-(double t_a, AffExpr&& t_b) { - AffExpr result(std::move(t_b)); - result.constant() = t_a - result.constant(); - return result; - } - - template - AffExpr operator-(double t_a, const KeyT& t_b) { - AffExpr result(t_b); - result.constant() = t_a; - return result; - } - - template - AffExpr operator-(const AffExpr& t_a, double t_b) { - AffExpr result(t_a); - result.constant() -= t_b; - return result; - } - - template - AffExpr operator-(double t_a, const AffExpr& t_b) { - AffExpr result(t_b); - result.constant() = t_a; - return result; - } - - template - AffExpr operator-(const KeyT& t_a, AffExpr&& t_b) { - AffExpr result(t_a); - result -= std::move(t_b); - return result; - } - - template - AffExpr operator-(AffExpr&& t_a, const KeyT& t_b) { - AffExpr result(std::move(t_a)); - result -= t_b; - return result; - } - - template - AffExpr operator-(const AffExpr& t_a, const KeyT& t_b) { - AffExpr result(t_a); - result -= t_b; - return result; - } - - template - AffExpr operator-(const KeyT& t_a, const AffExpr& t_b) { - AffExpr result(t_a); - result -= t_b; - return result; - } - - template - AffExpr operator-(LinExpr&& t_a, AffExpr&& t_b) { - AffExpr result(std::move(t_a)); - result -= std::move(t_b); - return result; - } - - template - AffExpr operator-(const AffExpr& t_a, LinExpr&& t_b) { - AffExpr result(t_a); - result -= std::move(t_b); - return result; - } - - template - AffExpr operator-(LinExpr&& t_a, const AffExpr& t_b) { - AffExpr result(std::move(t_a)); - result -= t_b; - return result; - } - - template - AffExpr operator-(const LinExpr& t_a, AffExpr&& t_b) { - AffExpr result(t_a); - result -= std::move(t_b); - return result; - } - - template - AffExpr operator-(const AffExpr& t_a, const LinExpr& t_b) { - AffExpr result(t_a); - result -= t_b; - return result; - } - - template - AffExpr operator-(const LinExpr& t_a, const AffExpr& t_b) { - AffExpr result(t_a); - result -= t_b; - return result; - } - - template - AffExpr operator-(const AffExpr& t_a, AffExpr&& t_b) { - AffExpr result(t_a); - result -= std::move(t_b); - return result; - } - - template - AffExpr operator-(AffExpr&& t_a, AffExpr&& t_b) { - AffExpr result(t_a); - result -= std::move(t_b); - return result; - } - - template - AffExpr operator-(AffExpr&& t_a, const AffExpr& t_b) { - AffExpr result(std::move(t_a)); - result -= t_b; - return result; - } - - template - AffExpr operator-(const AffExpr& t_a, const AffExpr& t_b) { - AffExpr result(t_a); - result -= t_b; - return result; - } - - // QuadExpr - - template - QuadExpr operator-(const QuadExpr& t_expr) { - QuadExpr result; - result -= t_expr; - return result; - } - - template - QuadExpr operator-(const QuadExpr& t_a, const QuadExpr& t_b) { - QuadExpr result(t_a); - result -= t_b; - return result; - } - - template - QuadExpr operator-(QuadExpr&& t_a, const QuadExpr& t_b) { - QuadExpr result(std::move(t_a)); - result -= t_b; - return result; - } - - template - QuadExpr operator-(const QuadExpr& t_a, QuadExpr&& t_b) { - QuadExpr result(t_a); - result -= std::move(t_b); - return result; - } - - template - QuadExpr operator-(QuadExpr&& t_a, QuadExpr&& t_b) { - QuadExpr result(std::move(t_a)); - result -= std::move(t_b); - return result; - } - - template - QuadExpr operator-(const QuadExpr& t_a, AffExpr&& t_b) { - QuadExpr result(t_a); - result -= std::move(t_b); - return result; - } - - template - QuadExpr operator-(AffExpr&& t_a, const QuadExpr& t_b) { - QuadExpr result(std::move(t_a)); - result -= t_b; - return result; - } - - template - QuadExpr operator-(const QuadExpr& t_a, LinExpr&& t_b) { - QuadExpr result(t_a); - result -= std::move(t_b); - return result; - } - - template - QuadExpr operator-(LinExpr&& t_a, const QuadExpr& t_b) { - QuadExpr result(std::move(t_a)); - result -= t_b; - return result; - } - - template - QuadExpr operator-(const QuadExpr& t_a, const AffExpr& t_b) { - QuadExpr result(t_a); - result -= t_b; - return result; - } - - template - QuadExpr operator-(const AffExpr& t_a, const QuadExpr& t_b) { - QuadExpr result(t_a); - result -= t_b; - return result; - } - - template - QuadExpr operator-(QuadExpr&& t_a, const AffExpr& t_b) { - QuadExpr result(std::move(t_a)); - result -= t_b; - return result; - } - - template - QuadExpr operator-(const AffExpr& t_a, QuadExpr&& t_b) { - QuadExpr result(t_a); - result -= std::move(t_b); - return result; - } - - template - QuadExpr operator-(QuadExpr&& t_a, LinExpr&& t_b) { - QuadExpr result(std::move(t_a)); - result -= std::move(t_b); - return result; - } +} - template - QuadExpr operator-(LinExpr&& t_a, QuadExpr&& t_b) { - QuadExpr result(std::move(t_a)); - result -= std::move(t_b); - return result; - } +#define DEFINE_OPERATOR_SINGLE(OPERATOR, OPERATOR_EQ, T, U, ResultT) \ +static ResultT operator OPERATOR(T t_a, U t_b) { \ + ResultT result(std::move(t_a)); \ + result OPERATOR_EQ std::move(t_b); \ + return result; \ +} - template - QuadExpr operator-(const QuadExpr& t_a, double t_b) { - QuadExpr result(t_a); - result -= t_b; - return result; - } +#define DEFINE_OPERATOR(OPERATOR, OPERATOR_EQ, T, U, ResultT) \ +DEFINE_OPERATOR_SINGLE(OPERATOR, OPERATOR_EQ, T, U, ResultT) \ +static ResultT operator OPERATOR(U t_a, T t_b) { \ + ResultT result(std::move(t_a)); \ + result OPERATOR_EQ std::move(t_b); \ + return result; \ +} - template - QuadExpr operator-(const ValueT& t_a, const QuadExpr& t_b) { - QuadExpr result(t_a); - result -= t_b; - return result; - } +#define DEFINE_COMMUTATIVE_OPERATOR_SINGLE(OPERATOR, OPERATOR_EQ, T, U, ResultT) \ +static ResultT operator OPERATOR(T t_a, U t_b) { \ + ResultT result(std::move(t_b)); \ + result OPERATOR_EQ std::move(t_a); \ + return result; \ +} - template - QuadExpr operator-(QuadExpr&& t_a, double t_b) { - QuadExpr result(std::move(t_a)); - result -= t_b; - return result; - } +#define DEFINE_COMMUTATIVE_OPERATOR(OPERATOR, OPERATOR_EQ, T, U, ResultT) \ +DEFINE_COMMUTATIVE_OPERATOR_SINGLE(OPERATOR, OPERATOR_EQ, T, U, ResultT) \ +static ResultT operator OPERATOR(U t_a, T t_b) { \ + ResultT result(std::move(t_a)); \ + result OPERATOR_EQ std::move(t_b); \ + return result; \ +} - template - QuadExpr operator-(double t_a, QuadExpr&& t_b) { - QuadExpr result(t_a); - result -= std::move(t_b); - return result; - } +#define DEFINE_OPERATIONS(T) \ +DEFINE_COMMUTATIVE_OPERATOR(+, +=, double, LinExpr, AffExpr) \ +DEFINE_COMMUTATIVE_OPERATOR(+, +=, double, AffExpr, AffExpr) \ +DEFINE_COMMUTATIVE_OPERATOR(+, +=, double, QuadExpr, QuadExpr) \ + \ +DEFINE_COMMUTATIVE_OPERATOR(+, +=, T, double, AffExpr) \ +DEFINE_COMMUTATIVE_OPERATOR_SINGLE(+, +=, T, T, LinExpr) \ +DEFINE_COMMUTATIVE_OPERATOR(+, +=, T, LinExpr, LinExpr) \ +DEFINE_COMMUTATIVE_OPERATOR(+, +=, T, AffExpr, AffExpr) \ +DEFINE_COMMUTATIVE_OPERATOR(+, +=, T, QuadExpr, QuadExpr) \ + \ +DEFINE_COMMUTATIVE_OPERATOR_SINGLE(+, +=, LinExpr, LinExpr, LinExpr) \ +DEFINE_COMMUTATIVE_OPERATOR(+, +=, LinExpr, AffExpr, AffExpr) \ +DEFINE_COMMUTATIVE_OPERATOR(+, +=, LinExpr, QuadExpr, QuadExpr) \ + \ +DEFINE_COMMUTATIVE_OPERATOR(+, +=, AffExpr, QuadExpr, QuadExpr) \ +DEFINE_COMMUTATIVE_OPERATOR_SINGLE(+, +=, AffExpr, AffExpr, AffExpr) \ + \ +DEFINE_COMMUTATIVE_OPERATOR_SINGLE(+, +=, QuadExpr, QuadExpr, QuadExpr) \ + \ +DEFINE_OPERATOR(-, -=, double, T, AffExpr) \ +DEFINE_OPERATOR(-, -=, double, LinExpr, AffExpr) \ +DEFINE_OPERATOR(-, -=, double, AffExpr, AffExpr) \ + \ +DEFINE_OPERATOR_SINGLE(-, -=, T, T, LinExpr) \ +DEFINE_OPERATOR(-, -=, T, LinExpr, LinExpr) \ +DEFINE_OPERATOR(-, -=, T, AffExpr, AffExpr) \ +DEFINE_OPERATOR(-, -=, T, QuadExpr, QuadExpr) \ + \ +DEFINE_OPERATOR_SINGLE(-, -=, LinExpr, LinExpr, LinExpr) \ +DEFINE_OPERATOR(-, -=, LinExpr, AffExpr, AffExpr) \ +DEFINE_OPERATOR(-, -=, LinExpr, QuadExpr, QuadExpr) \ + \ +DEFINE_OPERATOR_SINGLE(-, -=, AffExpr, AffExpr, AffExpr) \ +DEFINE_OPERATOR(-, -=, AffExpr, QuadExpr, QuadExpr) \ + \ +DEFINE_OPERATOR_SINGLE(-, -=, QuadExpr, QuadExpr, QuadExpr) \ + \ +DEFINE_COMMUTATIVE_OPERATOR(*, *=, double, T, LinExpr) \ +DEFINE_COMMUTATIVE_OPERATOR(*, *=, double, LinExpr, LinExpr) \ +DEFINE_COMMUTATIVE_OPERATOR(*, *=, double, AffExpr, AffExpr) \ +DEFINE_COMMUTATIVE_OPERATOR(*, *=, double, QuadExpr, QuadExpr) \ +\ +static QuadExpr operator*(T t_a, T t_b) { return { t_a, t_b }; } \ +\ +static LinExpr operator+(const T& t_a) { return t_a; } \ +static LinExpr operator-(const T& t_a) { return { -1., t_a }; } +namespace idol { + DEFINE_OPERATIONS(Var) + DEFINE_OPERATIONS(Ctr) } #endif //IDOL_OPERATORS_H diff --git a/lib/include/idol/mixed-integer/modeling/expressions/operations/operators_utils.h b/lib/include/idol/mixed-integer/modeling/expressions/operations/operators_utils.h index ca458b3e..94ddc29c 100644 --- a/lib/include/idol/mixed-integer/modeling/expressions/operations/operators_utils.h +++ b/lib/include/idol/mixed-integer/modeling/expressions/operations/operators_utils.h @@ -34,18 +34,30 @@ class idol::Range { [[nodiscard]] iterator end() const { return iterator(m_end); } }; -#define idol_Sum(iterator_name, iterator, expr) \ -[&]() { \ - using namespace ::idol; \ - AffExpr _idol_result; \ - auto _idol_iterator = iterator; \ - for (auto _idol_iterator_begin = _idol_iterator.begin(), _idol_iterator_end = _idol_iterator.end() ; \ - _idol_iterator_begin != _idol_iterator_end ; \ - ++_idol_iterator_begin) { \ - decltype(*_idol_iterator_begin) iterator_name = *_idol_iterator_begin; \ - _idol_result += expr; \ - } \ - return _idol_result; \ + +#define idol_Sum(INDEX, ITERABLE, EXPR) \ +[&]() { \ + const auto compute_sum = [&]() { \ + const auto& __idol_iterable = ITERABLE; \ + auto __idol_it = __idol_iterable.begin(); \ + auto __idol_end = __idol_iterable.end(); \ + auto INDEX = *__idol_it; \ + decltype(EXPR + EXPR) result = EXPR; \ + for (++__idol_it ; __idol_it != __idol_end ; ++__idol_it) { \ + INDEX = *__idol_it; \ + result += EXPR; \ + } \ + return result; \ + }; \ + \ + const auto& __idol_iterable = ITERABLE; \ + auto __idol_it = __idol_iterable.begin(); \ + auto __idol_end = __idol_iterable.end(); \ + if (__idol_it != __idol_end) { \ + return compute_sum(); \ + } \ + return decltype(compute_sum()){}; \ }() + #endif //IDOL_OPERATORS_UTILS_H diff --git a/lib/include/idol/mixed-integer/modeling/models/Dualizer.h b/lib/include/idol/mixed-integer/modeling/models/Dualizer.h new file mode 100644 index 00000000..a689fd5b --- /dev/null +++ b/lib/include/idol/mixed-integer/modeling/models/Dualizer.h @@ -0,0 +1,28 @@ +// +// Created by henri on 21.11.24. +// + +#ifndef IDOL_DUALIZER_H +#define IDOL_DUALIZER_H + +#include +#include +#include "idol/mixed-integer/modeling/variables/Var.h" +#include "idol/mixed-integer/modeling/constraints/Ctr.h" +#include "idol/mixed-integer/modeling/constraints/QCtr.h" + +namespace idol { + class Dualizer; + class Model; +} + +class idol::Dualizer { + const Model& m_parent; + + std::vector m_dual_variables; // constraint - qconstraint index <-> dual variable + std::vector> m_dual_constraints; // variable index <-> dual constraint +public: + explicit Dualizer(const Model& t_parent); +}; + +#endif //IDOL_DUALIZER_H diff --git a/lib/src/mixed-integer/modeling/models/Dualizer.cpp b/lib/src/mixed-integer/modeling/models/Dualizer.cpp new file mode 100644 index 00000000..60d054d8 --- /dev/null +++ b/lib/src/mixed-integer/modeling/models/Dualizer.cpp @@ -0,0 +1,9 @@ +// +// Created by henri on 21.11.24. +// + +#include "idol/mixed-integer/modeling/models/Dualizer.h" + +idol::Dualizer::Dualizer(const Model& t_model) : m_parent(t_model) { + +} \ No newline at end of file diff --git a/lib/src/mixed-integer/modeling/models/KKT.cpp b/lib/src/mixed-integer/modeling/models/KKT.cpp index 3b183cb8..f519f36e 100644 --- a/lib/src/mixed-integer/modeling/models/KKT.cpp +++ b/lib/src/mixed-integer/modeling/models/KKT.cpp @@ -188,7 +188,7 @@ void idol::Reformulators::KKT::create_dual_constraint(const idol::Var &t_var) { expr += dual_var.value(); } - AffExpr obj = m_description.follower_obj().linear().get(t_var); + AffExpr obj = m_description.follower_obj().linear().get(t_var); m_dual_constraints[index] = Ctr(env, expr == obj, "dual_" + t_var.name()); diff --git a/lib/src/mixed-integer/optimizers/wrappers/Gurobi/Optimizers_Gurobi.cpp b/lib/src/mixed-integer/optimizers/wrappers/Gurobi/Optimizers_Gurobi.cpp index cd43c64d..006c0a5b 100644 --- a/lib/src/mixed-integer/optimizers/wrappers/Gurobi/Optimizers_Gurobi.cpp +++ b/lib/src/mixed-integer/optimizers/wrappers/Gurobi/Optimizers_Gurobi.cpp @@ -491,7 +491,7 @@ idol::Model idol::Optimizers::Gurobi::read_from_file(idol::Env &t_env, const std const auto parse_linear = [&](const GRBLinExpr& t_lin_expr) { - AffExpr result_ = t_lin_expr.getConstant(); + AffExpr result_ = t_lin_expr.getConstant(); auto& linear_ = result_.linear(); const auto n_terms = t_lin_expr.size(); linear_.reserve(n_terms);