20 std::list<Var> m_branching_candidates;
25 const auto& primal_solution = t_node.info().primal_solution();
26 const double tol_integer = this->parent().get_tol_integer();
28 for (
const auto& var : m_branching_candidates) {
29 if (
const double value = primal_solution.get(var) ; !is_integer(value, tol_integer)) {
37 virtual std::list<std::pair<Var, double>> scoring_function(
const std::list<Var>& t_variables,
const Node<NodeInfoT> &t_node) = 0;
39 virtual std::list<NodeInfoT *> create_child_nodes_for_selected_variable(
const Node<NodeInfoT> &t_node,
const Var& t_var) {
41 const auto& primal_solution = t_node.info().primal_solution();
42 const double value = primal_solution.get(t_var);
43 const double lb = std::ceil(value);
44 const double ub = std::floor(value);
46 auto* n1 = t_node.info().create_child();
47 n1->add_branching_variable(t_var, GreaterOrEqual, lb);
49 auto* n2 = t_node.info().create_child();
50 n2->add_branching_variable(t_var, LessOrEqual, ub);
55 virtual std::list<NodeInfoT *> create_child_nodes(
const Node<NodeInfoT> &t_node) {
57 const auto& primal_solution = t_node.info().primal_solution();
59 auto invalid_variables = get_invalid_variables(primal_solution);
61 if (invalid_variables.empty()) {
65 Var selected_variable = invalid_variables.front();
67 if (invalid_variables.size() > 1) {
68 auto scores = scoring_function(invalid_variables, t_node);
69 selected_variable = get_argmax_score(scores);
72 return create_child_nodes_for_selected_variable(t_node, selected_variable);
75 [[nodiscard]]
const std::list<Var>& branching_candidates()
const {
return m_branching_candidates; }
78 : BranchingRule<NodeInfoT>(t_parent),
79 m_branching_candidates(std::move(t_branching_candidates)) {
84 std::list<Var> get_invalid_variables(
const PrimalPoint& t_primal_solution) {
86 std::list<Var> result;
87 const double tol_integer = this->parent().get_tol_integer();
89 for (
const auto& var : m_branching_candidates) {
90 if (
const double value = t_primal_solution.get(var) ; !is_integer(value, tol_integer)) {
91 result.emplace_back(var);
98 Var get_argmax_score(
const std::list<std::pair<Var, double>>& t_scores) {
100 if (t_scores.empty()) {
101 throw Exception(
"VariableScoringFunction returned an empty list.");
104 double max = std::numeric_limits<double>::lowest();
105 std::optional<Var> argmax;
107 for (
const auto& [var, score] : t_scores) {
114 if (!argmax.has_value()) {
115 throw Exception(
"Could not compute argmax of scores while searching for branching variable.");
118 return argmax.value();