5#ifndef IDOL_BRANCHANDBOUND_H 
    6#define IDOL_BRANCHANDBOUND_H 
    9#include "idol/general/optimizers/OptimizerFactory.h" 
   10#include "Optimizers_BranchAndBound.h" 
   11#include "idol/mixed-integer/optimizers/branch-and-bound/callbacks/BranchAndBoundCallbackFactory.h" 
   12#include "idol/mixed-integer/optimizers/branch-and-bound/callbacks/BranchAndBoundCallback.h" 
   13#include "idol/mixed-integer/optimizers/branch-and-bound/callbacks/CallbackAsBranchAndBoundCallback.h" 
   14#include "idol/mixed-integer/optimizers/callbacks/CallbackFactory.h" 
   15#include "idol/mixed-integer/optimizers/branch-and-bound/nodes/DefaultNodeInfo.h" 
   16#include "idol/mixed-integer/optimizers/branch-and-bound/logs/Factory.h" 
   17#include "idol/mixed-integer/optimizers/branch-and-bound/logs/Info.h" 
   28template<
class NodeT = 
idol::DefaultNodeInfo>
 
   30    std::unique_ptr<OptimizerFactory> m_relaxation_optimizer_factory;
 
   31    std::unique_ptr<BranchingRuleFactory<NodeT>> m_branching_rule_factory;
 
   32    std::unique_ptr<NodeSelectionRuleFactory<NodeT>> m_node_selection_rule_factory;
 
   33    std::unique_ptr<Logs::BranchAndBound::Factory<NodeT>> m_logger_factory;
 
   35    std::list<std::unique_ptr<BranchAndBoundCallbackFactory<NodeT>>> m_callbacks;
 
   37    std::optional<unsigned int> m_subtree_depth;
 
   38    std::optional<unsigned int> m_log_frequency;
 
   46    template<
class ReturnT, 
class T> 
using only_if_has_Strategy = 
typename std::pair<typename T::template Strategy<NodeT>, ReturnT>::second_type;
 
  111    template<
class BranchingRuleFactoryT>
 
  142    template<
class NodeSelectionRuleFactoryT>
 
 
  211    m_relaxation_optimizer_factory.reset(t_node_optimizer.clone());
 
  218    if (m_logger_factory) {
 
  219        throw Exception(
"Logs have already been configured.");
 
  222    m_logger_factory.reset(t_log_factory.clone());
 
  241    m_callbacks.emplace_back(t_callback.clone());
 
 
  249    if (m_subtree_depth.has_value()) {
 
  250        throw Exception(
"A subtree depth has already been given");
 
  253    m_subtree_depth = t_depth;
 
 
  259template<
class NodeSelectionRuleFactoryT>
 
  262    return with_node_selection_rule(
typename NodeSelectionRuleFactoryT::template Strategy<NodeT>(t_node_selection_rule));
 
  269    if (m_node_selection_rule_factory) {
 
  270        throw Exception(
"A node selection rule has already been set.");
 
  273    m_node_selection_rule_factory.reset(t_node_selection.clone());
 
 
  279template<
class BranchingRuleFactoryT>
 
  282    return with_branching_rule(
typename BranchingRuleFactoryT::template Strategy<NodeT>(t_branching_rule));
 
  288    if (m_branching_rule_factory) {
 
  289        throw Exception(
"A branching rule has already been set.");
 
  292    m_branching_rule_factory.reset(t_branching_rule.clone());
 
 
  300    if (m_relaxation_optimizer_factory) {
 
  301        throw Exception(
"A node solver has already been set.");
 
  304    m_relaxation_optimizer_factory.reset(t_node_optimizer.
clone());
 
 
  313          m_relaxation_optimizer_factory(t_rhs.m_relaxation_optimizer_factory ? t_rhs.m_relaxation_optimizer_factory->
clone() : nullptr),
 
  314          m_branching_rule_factory(t_rhs.m_branching_rule_factory ? t_rhs.m_branching_rule_factory->
clone() : nullptr),
 
  315          m_node_selection_rule_factory(t_rhs.m_node_selection_rule_factory ? t_rhs.m_node_selection_rule_factory->
clone() : nullptr),
 
  316          m_subtree_depth(t_rhs.m_subtree_depth),
 
  317          m_logger_factory(t_rhs.m_logger_factory ? t_rhs.m_logger_factory->
clone() : nullptr) {
 
  319    for (
auto& cb : t_rhs.m_callbacks) {
 
  320        m_callbacks.emplace_back(cb->clone());
 
 
  328    if (!m_relaxation_optimizer_factory) {
 
  329        throw Exception(
"No node solver has been given, please call BranchAndBound::with_node_optimizer to configure.");
 
  332    if (!m_branching_rule_factory) {
 
  333        throw Exception(
"No branching rule has been given, please call BranchAndBound::with_branching_rule to configure.");
 
  336    if (!m_node_selection_rule_factory) {
 
  337        throw Exception(
"No node selection rule has been given, please call BranchAndBound::with_node_selection_rule to configure.");
 
  340    std::unique_ptr<Logs::BranchAndBound::Factory<NodeT>> default_logger_factory;
 
  341    if (!m_logger_factory) {
 
  342        default_logger_factory = std::make_unique<Logs::BranchAndBound::Info<NodeT>>();
 
  346                                                         *m_relaxation_optimizer_factory,
 
  347                                                         *m_branching_rule_factory,
 
  348                                                         *m_node_selection_rule_factory,
 
  350                                                         m_logger_factory ? *m_logger_factory : *default_logger_factory);
 
  352    this->handle_default_parameters(result);
 
  354    if (m_subtree_depth.has_value()) {
 
  355        result->set_subtree_depth(m_subtree_depth.value());
 
  358    for (
auto& cb : m_callbacks) {
 
  359        result->add_callback(cb->operator()());
 
 
  371    template<
class NodeInfoT>
 
  374        result += t_node_optimizer;
 
only_if_has_Strategy< BranchAndBound< NodeT > &, BranchingRuleFactoryT > with_branching_rule(const BranchingRuleFactoryT &t_branching_rule)
BranchAndBound< NodeT > & with_branching_rule(const BranchingRuleFactory< NodeT > &t_branching_rule)
BranchAndBound< NodeT > & with_node_selection_rule(const NodeSelectionRuleFactory< NodeT > &t_node_selection)
BranchAndBound< NodeT > & with_node_optimizer(const OptimizerFactory &t_node_optimizer)
BranchAndBound< NodeT > & add_callback(const BranchAndBoundCallbackFactory< NodeT > &t_callback)
OptimizerFactory * clone() const override
typename std::pair< typename T::template Strategy< NodeT >, ReturnT >::second_type only_if_has_Strategy
BranchAndBound< NodeT > & with_subtree_depth(unsigned int t_depth)
only_if_has_Strategy< BranchAndBound< NodeT > &, NodeSelectionRuleFactoryT > with_node_selection_rule(const NodeSelectionRuleFactoryT &t_node_selection_rule)
Optimizer * operator()(const Model &t_model) const override
virtual OptimizerFactory * clone() const =0