5#ifndef IDOL_DEFAULTNODEUPDATOR_H
6#define IDOL_DEFAULTNODEUPDATOR_H
8#include "NodeUpdator.h"
9#include "idol/mixed-integer/modeling/models/Model.h"
10#include "idol/general/utils/Map.h"
12#include "DefaultNodeInfo.h"
13#include "BranchingDecision.h"
17 class DefaultNodeUpdator;
20template<
class NodeInfoT>
23 const Model& m_parent;
26 Map<Var, double> m_changed_lower_bounds;
27 Map<Var, double> m_changed_upper_bounds;
28 std::list<Ctr> m_added_constraints;
31 Map<Var, double> &t_changed_lower_bounds,
32 Map<Var, double> &t_changed_upper_bounds);
35 Map<Var, double> &t_current_changed_bounds,
36 Map<Var, double> &t_changed_bounds);
38 void apply_constraint_branching_decisions(
const Node<NodeInfoT> &t_node);
44 void initialize()
override {}
48 void clear()
override;
51 Model& relaxation() {
return m_relaxation; }
53 [[nodiscard]]
const Model& relaxation()
const {
return m_relaxation; }
56template<
class NodeInfoT>
60 if (t_node.level() == 0) {
64 apply_constraint_branching_decisions(t_node.parent());
66 for (
const auto& [ctr, temporary_constraint] : t_node.info().constraint_branching_decisions()) {
67 m_relaxation.add(ctr, temporary_constraint);
68 m_added_constraints.emplace_back(ctr);
75 : m_parent(t_parent), m_relaxation(t_relaxation) {
79template<
class NodeInfoT>
83 for (
const auto& [var, lb] : m_changed_lower_bounds) {
84 m_relaxation.set_var_lb(var, lb);
86 m_changed_lower_bounds.clear();
89 for (
const auto& [var, ub] : m_changed_upper_bounds) {
90 m_relaxation.set_var_ub(var, ub);
92 m_changed_upper_bounds.clear();
95 for (
const auto& ctr : m_added_constraints) {
96 m_relaxation.remove(ctr);
98 m_added_constraints.clear();
101template<
class NodeInfoT>
104 Map<Var, double> changed_lower_bounds;
105 Map<Var, double> changed_upper_bounds;
107 apply_variable_branching_decisions(t_node, changed_lower_bounds, changed_upper_bounds);
109 m_changed_lower_bounds = changed_lower_bounds;
110 m_changed_upper_bounds = changed_upper_bounds;
112 apply_constraint_branching_decisions(t_node);
115template<
class NodeInfoT>
117 Map<Var, double> &t_changed_lower_bounds,
118 Map<Var, double> &t_changed_upper_bounds
121 for (
const auto& branching_decision : t_node.info().variable_branching_decisions()) {
123 switch (branching_decision.type) {
125 apply_variable_branching_decision(branching_decision, m_changed_upper_bounds, t_changed_upper_bounds);
128 apply_variable_branching_decision(branching_decision, m_changed_lower_bounds, t_changed_lower_bounds);
131 throw Exception(
"Branching on equality constraints is not implemented.");
136 if (t_node.level() == 0) {
140 apply_variable_branching_decisions(t_node.parent(), t_changed_lower_bounds, t_changed_upper_bounds);
144template<
class NodeInfoT>
146 idol::Map<idol::Var, double> &t_current_changed_bounds,
147 idol::Map<idol::Var, double> &t_changed_bounds) {
149 const auto& var = t_branching_decision.variable;
151 if (
const auto it = t_changed_bounds.find(var) ; it != t_changed_bounds.end()) {
155 const double bound = t_branching_decision.bound;
156 double original_bound;
158 if (t_branching_decision.type == LessOrEqual) {
160 original_bound = m_relaxation.get_var_ub(var);
161 m_relaxation.set_var_ub(var, bound);
165 original_bound = m_relaxation.get_var_lb(var);
166 m_relaxation.set_var_lb(var, bound);
170 if (
const auto it = t_current_changed_bounds.find(var) ; it != t_current_changed_bounds.end()) {
171 t_changed_bounds.emplace(*it);
172 t_current_changed_bounds.erase(it);
174 t_changed_bounds.emplace(var, original_bound);