5#ifndef IDOL_BRANCHANDBOUNDCALLBACK_H 
    6#define IDOL_BRANCHANDBOUNDCALLBACK_H 
    8#include "idol/mixed-integer/optimizers/callbacks/Callback.h" 
    9#include "idol/mixed-integer/optimizers/branch-and-bound/nodes/Node.h" 
   10#include "idol/mixed-integer/optimizers/branch-and-bound/Optimizers_BranchAndBound.h" 
   11#include "AbstractBranchAndBoundCallbackI.h" 
   12#include "CallbackAsBranchAndBoundCallback.h" 
   16    template<
class NodeInfoT>
 
   17    class BranchAndBoundCallback;
 
   19    template<
class NodeInfoT>
 
   20    class BranchAndBoundCallbackI;
 
   26template<
class NodeInfoT>
 
   30    std::list<std::unique_ptr<BranchAndBoundCallback<NodeInfoT>>> m_callbacks;
 
   33    std::optional<Node<NodeInfoT>> m_node;
 
   34    Model* m_relaxation = 
nullptr;
 
   40    void add_user_cut(
const TempCtr &t_cut);
 
   42    void add_lazy_cut(
const TempCtr &t_cut);
 
   44    void add_local_variable_branching(
const idol::Var &t_var, CtrType t_type, 
double t_rhs);
 
   48    [[nodiscard]] 
const Model& relaxation() 
const;
 
   50    [[nodiscard]] 
const Model& original_model() 
const;
 
   52    [[nodiscard]] 
const Timer& time() 
const;
 
   56    void submit_heuristic_solution(NodeInfoT* t_info);
 
   58    void submit_bound(
double t_bound);
 
   60    [[nodiscard]] 
double best_bound() 
const;
 
   62    [[nodiscard]] 
double best_obj() 
const;
 
   68            CallbackEvent t_event,
 
   70            Model *t_relaxation) 
override;
 
   76    void log_after_termination() 
override;
 
 
   79template<
class NodeInfoT>
 
   81    m_node->info().add_branching_variable(t_var, t_type, t_rhs);
 
   82    m_registry->n_added_local_variable_branching++;
 
   85template<
class NodeInfoT>
 
   87    m_parent->terminate();
 
   90template<
class NodeInfoT>
 
   92    return m_parent->get_best_obj();
 
   95template<
class NodeInfoT>
 
   97    return m_parent->get_best_bound();
 
  100template<
class NodeInfoT>
 
  103    if (m_callbacks.empty()) {
 
  107    std::cout << 
"Callbacks:" << std::endl;
 
  109    for (
auto& ptr_to_cb : m_callbacks) {
 
  110        ptr_to_cb->log_after_termination();
 
  113    std::cout << std::endl;
 
  117template<
class NodeInfoT>
 
  120        throw Exception(
"No side effect registry was found");
 
  125template<
class NodeInfoT>
 
  127    return m_parent->time();
 
  130template<
class NodeInfoT>
 
  147    virtual void log_after_termination() {}
 
  161    void add_local_variable_branching(
const Var &t_var, CtrType t_type, 
double t_rhs);
 
  204    [[nodiscard]] 
const Timer& time() 
const;
 
  206    double best_bound() 
const;
 
  208    double best_obj() 
const;
 
  214    void throw_if_no_interface() 
const;
 
 
  219template<
class NodeInfoT>
 
  221    throw_if_no_interface();
 
  222    m_interface->add_local_variable_branching(t_var, t_type, t_rhs);
 
  225template<
class NodeInfoT>
 
  227    throw_if_no_interface();
 
  228    return m_interface->best_obj();
 
  231template<
class NodeInfoT>
 
  233    throw_if_no_interface();
 
  234    return m_interface->best_bound();
 
  237template<
class NodeInfoT>
 
  239    throw_if_no_interface();
 
  240    m_interface->terminate();
 
  243template<
class NodeInfoT>
 
  245    throw_if_no_interface();
 
  246    return m_interface->side_effect_registry();
 
 
  249template<
class NodeInfoT>
 
  251    throw_if_no_interface();
 
  252    return m_interface->time();
 
  255template<
class NodeInfoT>
 
  257    throw_if_no_interface();
 
  258    m_interface->submit_bound(t_bound);
 
 
  261template<
class NodeInfoT>
 
  263    throw_if_no_interface();
 
  264    m_interface->submit_heuristic_solution(t_info);
 
 
  267template<
class NodeInfoT>
 
  269    throw_if_no_interface();
 
  270    return m_interface->original_model();
 
 
  273template<
class NodeInfoT>
 
  275    throw_if_no_interface();
 
  276    return m_interface->relaxation();
 
 
  279template<
class NodeInfoT>
 
  281    throw_if_no_interface();
 
  282    return m_interface->node();
 
 
  285template<
class NodeInfoT>
 
  287    throw_if_no_interface();
 
  288    m_interface->add_lazy_cut(t_cut);
 
 
  291template<
class NodeInfoT>
 
  293    throw_if_no_interface();
 
  294    m_interface->add_user_cut(t_cut);
 
 
  297template<
class NodeInfoT>
 
  300        throw Exception(
"No interface was found.");
 
  304template<
class NodeInfoT>
 
  307                                                     CallbackEvent t_event,
 
  308                                                     const Node<NodeInfoT> &t_current_node,
 
  309                                                     Model *t_relaxation) {
 
  310    SideEffectRegistry result;
 
  313    m_node = t_current_node;
 
  314    m_relaxation = t_relaxation;
 
  315    m_registry = &result;
 
  317    for (
auto &cb: m_callbacks) {
 
  318        cb->m_interface = 
this;
 
  319        cb->operator()(t_event);
 
  320        cb->m_interface = 
nullptr;
 
  325    m_relaxation = 
nullptr;
 
  326    m_registry = 
nullptr;
 
  331template<
class NodeInfoT>
 
  333    m_callbacks.emplace_back(t_cb);
 
  336template<
class NodeInfoT>
 
  341    for (
auto& ptr_callback : m_callbacks) {
 
  342        ptr_callback->m_interface = 
this;
 
  343        ptr_callback->initialize();
 
  344        ptr_callback->m_interface = 
nullptr;
 
  351template<
class NodeInfoT>
 
  354        throw Exception(
"submit_bound is not accessible in this context.");
 
  356    m_parent->submit_lower_bound(t_bound);
 
  359template<
class NodeInfoT>
 
  362        throw Exception(
"submit_heuristic_solution is not accessible in this context.");
 
  364    m_parent->submit_heuristic_solution(t_info);
 
  367template<
class NodeInfoT>
 
  370        throw Exception(
"original_model is not accessible in this context.");
 
  372    return m_parent->parent();
 
  375template<
class NodeInfoT>
 
  378        throw Exception(
"relaxation is not accessible in this context.");
 
  380    return *m_relaxation;
 
  383template<
class NodeInfoT>
 
  386        throw Exception(
"node is not accessible in this context.");
 
  391template<
class NodeInfoT>
 
  393    m_relaxation->add_ctr(t_cut);
 
  394    ++m_registry->n_added_lazy_cuts;
 
  397template<
class NodeInfoT>
 
  399    m_relaxation->add_ctr(t_cut);
 
  400    ++m_registry->n_added_user_cuts;
 
virtual void operator()(CallbackEvent t_event)=0
void submit_heuristic_solution(NodeInfoT *t_info)
void add_user_cut(const TempCtr &t_cut)
const Model & relaxation() const
const SideEffectRegistry & side_effect_registry() const
const Node< NodeInfoT > & node() const
void add_lazy_cut(const TempCtr &t_cut)
virtual void initialize()
void submit_bound(double t_bound)
const Model & original_model() const