Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
hlefebvr committed Nov 15, 2023
2 parents e6a040f + 98277d4 commit c652db7
Show file tree
Hide file tree
Showing 52 changed files with 816 additions and 828 deletions.
2 changes: 1 addition & 1 deletion dev/main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "idol/modeling.h"
#include "idol/problems/generalized-assignment-problem/GAP_Instance.h"
#include "idol/optimizers/branch-and-bound/nodes/NodeVarInfo.h"
#include "idol/optimizers/branch-and-bound/nodes/DefaultNodeInfo.h"
#include "idol/optimizers/branch-and-bound/BranchAndBound.h"
#include "idol/optimizers/branch-and-bound/branching-rules/factories/MostInfeasible.h"
#include "idol/optimizers/branch-and-bound/node-selection-rules/factories/BestBound.h"
Expand Down
9 changes: 5 additions & 4 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ add_library(idol STATIC
include/idol/optimizers/branch-and-bound/nodes/Node.h
include/idol/optimizers/branch-and-bound/nodes/NodeUpdator.h
include/idol/optimizers/branch-and-bound/node-selection-rules/impls/DepthFirst.h
include/idol/optimizers/branch-and-bound/branching-rules/impls/VariableBranchingRule.h
include/idol/optimizers/branch-and-bound/node-selection-rules/factories/BreadthFirst.h
include/idol/optimizers/branch-and-bound/node-selection-rules/factories/WorstBound.h
include/idol/optimizers/branch-and-bound/node-selection-rules/factories/BestBound.h
Expand Down Expand Up @@ -154,9 +153,9 @@ add_library(idol STATIC
src/optimizers/branch-and-bound/branching-rules/factories/StrongBranchingPhase.cpp
include/idol/optimizers/branch-and-bound/branching-rules/factories/PseudoCost.h
include/idol/optimizers/branch-and-bound/branching-rules/impls/PseudoCost.h
include/idol/optimizers/branch-and-bound/nodes/NodeVarInfo.h
include/idol/optimizers/branch-and-bound/nodes/NodeVarUpdator.h
src/optimizers/branch-and-bound/nodes/NodeVarInfo.cpp
include/idol/optimizers/branch-and-bound/nodes/DefaultNodeInfo.h
include/idol/optimizers/branch-and-bound/nodes/DefaultNodeUpdator.h
src/optimizers/branch-and-bound/nodes/DefaultNodeInfo.cpp
include/idol/optimizers/wrappers/HiGHS/HiGHS.h
src/optimizers/wrappers/HiGHS/HiGHS.cpp
src/optimizers/wrappers/HiGHS/Optimizers_HiGHS.cpp
Expand Down Expand Up @@ -197,6 +196,8 @@ add_library(idol STATIC
include/idol/optimizers/branch-and-bound/branching-rules/factories/BracnhingWithPriority.h
src/optimizers/logs.cpp
include/idol/optimizers/branch-and-bound/branching-rules/impls/BranchingWithPriority.h
include/idol/optimizers/branch-and-bound/nodes/BranchingDecision.h
include/idol/containers/Pair.h
)

find_package(OpenMP REQUIRED)
Expand Down
23 changes: 13 additions & 10 deletions lib/include/idol/containers/Map.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@

#ifdef IDOL_USE_ROBINHOOD
#include <robin_hood.h>

#else
#include <unordered_map>
#endif

// Implements hash for pairs (non-symmetric by default (std::hash<std::pair<T, U>>) and symmetric impls)
#include "Pair.h"

// Implements hash for pairs (non-symmetric by default (std::hash<idol::Pair<T, U>>) and symmetric impls)
// See https://youngforest.github.io/2020/05/27/best-implement-to-use-pair-as-key-to-std-unordered-map-in-C/
namespace idol::impl {

Expand Down Expand Up @@ -47,27 +50,27 @@ namespace idol::impl {

struct symmetric_pair_hash {
template<class Key>
std::size_t operator()(const std::pair<Key, Key> &t_pair) const {
std::size_t operator()(const idol::Pair<Key, Key> &t_pair) const {
return std::less<Key>()(t_pair.first, t_pair.second) ?
hash<std::pair<Key, Key>>()(t_pair)
: hash<std::pair<Key, Key>>()(std::make_pair(t_pair.second, t_pair.first));
hash<idol::Pair<Key, Key>>()(t_pair)
: hash<idol::Pair<Key, Key>>()(idol::Pair(t_pair.second, t_pair.first));
}
};

struct symmetric_pair_equal_to {
template<class Key>
std::size_t operator()(const std::pair<Key, Key>& t_a, const std::pair<Key, Key>& t_b) const {
const auto a = std::less<Key>()(t_a.first, t_a.second) ? t_a : std::make_pair(t_a.second, t_a.first);
const auto b = std::less<Key>()(t_b.first, t_b.second) ? t_b : std::make_pair(t_b.second, t_b.first);
std::size_t operator()(const idol::Pair<Key, Key>& t_a, const idol::Pair<Key, Key>& t_b) const {
const auto a = std::less<Key>()(t_a.first, t_a.second) ? t_a : idol::Pair(t_a.second, t_a.first);
const auto b = std::less<Key>()(t_b.first, t_b.second) ? t_b : idol::Pair(t_b.second, t_b.first);
return std::equal_to<Key>()(a.first, b.first) && std::equal_to<Key>()(a.second, b.second);
}
};

}

template<class Key1, class Key2>
struct std::hash<std::pair<Key1, Key2>> {
std::size_t operator()(const std::pair<Key1, Key2>& t_pair) const {
struct std::hash<idol::Pair<Key1, Key2>> {
std::size_t operator()(const idol::Pair<Key1, Key2>& t_pair) const {
return idol::impl::hash_val(t_pair.first, t_pair.second);
}
};
Expand Down Expand Up @@ -95,7 +98,7 @@ namespace idol {
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<const Key, T> >
class Allocator = std::allocator<idol::Pair<const Key, T> >
>
using Map = std::unordered_map<Key, T, Hash, KeyEqual, Allocator>;

Expand Down
29 changes: 29 additions & 0 deletions lib/include/idol/containers/Pair.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Created by henri on 15.11.23.
//

#ifndef IDOL_PAIR_H
#define IDOL_PAIR_H

namespace idol {
template<class T1, class T2> struct Pair;
}

template<class T1, class T2>
struct idol::Pair {
T1 first;
T2 second;
Pair(const T1& t_1, const T2& t_2) : first(t_1), second(t_2) {}

Pair(const Pair&) = default;
Pair(Pair&&) = default;

Pair& operator=(const Pair&) = default;
Pair& operator=(Pair&&) = default;

bool operator==(const Pair& t_rhs) const {
return std::equal_to<T1>()(first, t_rhs.first) && std::equal_to<T2>()(second, t_rhs.second);
}
};

#endif //IDOL_PAIR_H
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace idol {
SquareMatrix Q(indices);

for (const auto &[var1, var2, constant]: t_expr) {
if (var1 == var2) {
if (var1.id() == var2.id()) {
Q.set(var1, var2, constant.numerical());
} else {
Q.set(var1, var2, constant.numerical() / 2.);
Expand Down
12 changes: 8 additions & 4 deletions lib/include/idol/modeling/expressions/AbstractExpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "idol/modeling/matrix/MatrixCoefficient.h"
#include "idol/modeling/variables/Var.h"
#include "idol/errors/Exception.h"
#include "idol/containers/Pair.h"
#include <memory>
#include <utility>
#include <functional>
Expand Down Expand Up @@ -169,13 +170,16 @@ template<class Key, class IteratorOutputT, class Hash, class EqualTo>
idol::impl::AbstractExpr<Key, IteratorOutputT, Hash, EqualTo> &
idol::impl::AbstractExpr<Key, IteratorOutputT, Hash, EqualTo>::operator=(const impl::AbstractExpr<Key, IteratorOutputT, Hash, EqualTo> &t_src) {

if (this == &t_src) { return *this; }
if (this == &t_src) {
return *this;
}

m_map.clear();
for (const auto& [key, ptr_to_value] : t_src.m_map) {
m_map.template emplace(key, std::make_unique<MatrixCoefficient>(ptr_to_value->value()));
}
return *this;

return *this;
}

template<class Key, class IteratorOutputT, class Hash, class EqualTo>
Expand Down Expand Up @@ -325,11 +329,11 @@ class idol::impl::AbstractExpr<Key, IteratorOutputT, Hash, EqualTo>::const_itera
bool operator!=(const const_iterator& t_rhs) const { return m_it != t_rhs.m_it; }
bool operator==(const const_iterator& t_rhs) const { return m_it == t_rhs.m_it; }
const_iterator operator++() { ++m_it; return *this; }
IteratorOutputT operator*() const { return { m_it->first, m_it->second->value() }; }
IteratorOutputT operator*() const { return IteratorOutputT(m_it->first, m_it->second->value()); }
};

template<class Key,
class IteratorOutputT = std::pair<const Key&, const idol::Constant&>,
class IteratorOutputT = idol::Pair<const Key&, const idol::Constant&>,
class Hash = std::hash<Key>,
class EqualTo = std::equal_to<Key>
>
Expand Down
4 changes: 2 additions & 2 deletions lib/include/idol/modeling/expressions/Constant.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct idol::QuadParam {
*/
class idol::Constant {
Map<Param, double> m_linear_terms;
Map<std::pair<Param, Param>, double, idol::impl::symmetric_pair_hash, idol::impl::symmetric_pair_equal_to> m_quadratic_terms;
Map<idol::Pair<Param, Param>, double, idol::impl::symmetric_pair_hash, idol::impl::symmetric_pair_equal_to> m_quadratic_terms;
double m_constant = 0.;

void insert_or_add(const Param& t_param, double t_value);
Expand Down Expand Up @@ -285,7 +285,7 @@ namespace idol {
t_os << '!' << t_param.name();
};

const auto print_quad_term = [&t_os](const std::pair<idol::Param, idol::Param> &t_pair, double t_coeff) {
const auto print_quad_term = [&t_os](const auto &t_pair, double t_coeff) {
if (!idol::equals(t_coeff, 1., idol::Tolerance::Sparsity)) {
t_os << t_coeff << ' ';
}
Expand Down
13 changes: 7 additions & 6 deletions lib/include/idol/modeling/expressions/QuadExpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define IDOL_QUADEXPR_H

#include "AbstractExpr.h"
#include "idol/containers/Pair.h"

namespace idol {
template<class Key1, class Key2>
Expand All @@ -24,7 +25,7 @@ struct idol::QuadTerm {
const Key1& key1;
const Key2& key2;
const Constant& constant;
QuadTerm(const std::pair<Key1, Key2>& t_vars, const Constant& t_constant)
QuadTerm(const Pair<Key1, Key2>& t_vars, const Constant& t_constant)
: key1(t_vars.first), key2(t_vars.second), constant(t_constant) {}
};

Expand All @@ -33,18 +34,18 @@ template<class Key1 = idol::Var,
class Hash = std::conditional_t<
std::is_same_v<Key1, Key2>,
idol::impl::symmetric_pair_hash,
std::hash<std::pair<Key1, Key2>>
std::hash<idol::Pair<Key1, Key2>>
>,
class EqualTo = std::conditional_t<
std::is_same_v<Key1, Key2>,
idol::impl::symmetric_pair_equal_to,
std::equal_to<std::pair<Key1, Key2>>
std::equal_to<idol::Pair<Key1, Key2>>
>
>
class idol::QuadExpr : public AbstractExpr<std::pair<Key1, Key2>, QuadTerm<Key1, Key2>, Hash, EqualTo> {
class idol::QuadExpr : public AbstractExpr<idol::Pair<Key1, Key2>, QuadTerm<Key1, Key2>, Hash, EqualTo> {
friend class Matrix;

using ParentT = AbstractExpr<std::pair<Key1, Key2>, QuadTerm<Key1, Key2>, Hash, EqualTo>;
using ParentT = AbstractExpr<idol::Pair<Key1, Key2>, QuadTerm<Key1, Key2>, Hash, EqualTo>;
using ParentT::get;
using ParentT::set;
public:
Expand Down Expand Up @@ -83,7 +84,7 @@ idol::QuadExpr<Key1, Key2, Hash, EqualTo>::QuadExpr(const Constant &t_factor, co

template<class Key1, class Key2, class Hash, class EqualTo>
void idol::QuadExpr<Key1, Key2, Hash, EqualTo>::set(const Key1 &t_a, const Key2& t_b, Constant t_coefficient) {
return set(std::make_pair(t_a, t_b), std::move(t_coefficient));
return set({ t_a, t_b }, std::move(t_coefficient));
}

template<class Key1, class Key2, class Hash, class EqualTo>
Expand Down
21 changes: 7 additions & 14 deletions lib/include/idol/modeling/objects/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <memory>
#include "ObjectId.h"
#include "idol/containers/Vector.h"
#include "idol/containers/Pair.h"
#include "idol/modeling/annotations/Annotation.h"
#include "idol/errors/Exception.h"

Expand Down Expand Up @@ -55,20 +56,6 @@ class idol::Object {
*/
[[nodiscard]] unsigned int id() const { return m_object_id->id(); }

/**
* Returns true if the two optimization objects have the same id, false otherwise.
* @param t_rhs the other optimization object.
* @return True if the two optimization objects have the same id, false otherwise.
*/
bool operator==(const Object<T, CRTP>& t_rhs) const { return id() == t_rhs.id(); }

/**
* Returns false if the two optimization objects have the same id, true otherwise.
* @param t_rhs the other optimization object.
* @return False if the two optimization objects have the same id, true otherwise.
*/
bool operator!=(const Object<T, CRTP>& t_rhs) const { return id() != t_rhs.id(); }

/**
* Returns true if the optimization object is part of the model `t_model`, false otherwise.
* @param t_model The model.
Expand Down Expand Up @@ -154,6 +141,12 @@ struct std::less<idol::name> { \
std::size_t operator()(const idol::name& t_a, const idol::name& t_b) const { \
return t_a.id() < t_b.id(); \
} \
}; \
template<> \
struct std::equal_to<idol::Pair<idol::name, idol::name>> { \
std::size_t operator()(const idol::Pair<idol::name, idol::name>& t_a, const idol::Pair<idol::name, idol::name>& t_b) const { \
return std::equal_to<idol::name>()(t_a.first, t_b.first) && std::equal_to<idol::name>()(t_a.second, t_b.second); \
} \
};

#endif //IDOL_OBJECT_H
4 changes: 2 additions & 2 deletions lib/include/idol/optimizers/branch-and-bound/BranchAndBound.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include "idol/optimizers/branch-and-bound/callbacks/CallbackAsBranchAndBoundCallback.h"
#include "idol/optimizers/callbacks/CallbackFactory.h"
#include "idol/optimizers/branch-and-bound/cutting-planes/CuttingPlaneGenerator.h"
#include "idol/optimizers/branch-and-bound/nodes/NodeVarInfo.h"
#include "idol/optimizers/branch-and-bound/nodes/DefaultNodeInfo.h"

namespace idol {
template<class NodeT>
Expand All @@ -24,7 +24,7 @@ namespace idol {
* @tparam NodeT the class used to store nodes information.
* It is strongly advised to inherit from NodeVarInfo in order to create your own node type.
*/
template<class NodeT = idol::NodeVarInfo>
template<class NodeT = idol::DefaultNodeInfo>
class idol::BranchAndBound : public OptimizerFactoryWithDefaultParameters<BranchAndBound<NodeT>> {
std::unique_ptr<OptimizerFactory> m_relaxation_optimizer_factory;
std::unique_ptr<BranchingRuleFactory<NodeT>> m_branching_rule_factory;
Expand Down
Loading

0 comments on commit c652db7

Please sign in to comment.