20    std::list<Var> m_branching_candidates;
 
   25        const auto& primal_solution = t_node.info().primal_solution();
 
   27        for (
const auto& var : m_branching_candidates) {
 
   28            if (
const double value = primal_solution.get(var) ; !is_integer(value, 
Tolerance::Integer)) {
 
   36    virtual std::list<std::pair<Var, double>> scoring_function(
const std::list<Var>& t_variables, 
const Node<NodeInfoT> &t_node) = 0;
 
   38    virtual std::list<NodeInfoT *> create_child_nodes_for_selected_variable(
const Node<NodeInfoT> &t_node, 
const Var& t_var) {
 
   40        const auto& primal_solution = t_node.info().primal_solution();
 
   41        const double value = primal_solution.get(t_var);
 
   42        const double lb = std::ceil(value);
 
   43        const double ub = std::floor(value);
 
   45        auto* n1 = t_node.info().create_child();
 
   46        n1->add_branching_variable(t_var, GreaterOrEqual, lb);
 
   48        auto* n2 = t_node.info().create_child();
 
   49        n2->add_branching_variable(t_var, LessOrEqual, ub);
 
   54    virtual std::list<NodeInfoT *> create_child_nodes(
const Node<NodeInfoT> &t_node) {
 
   56        const auto& primal_solution = t_node.info().primal_solution();
 
   58        auto invalid_variables = get_invalid_variables(primal_solution);
 
   60        if (invalid_variables.empty()) {
 
   64        Var selected_variable = invalid_variables.front();
 
   66        if (invalid_variables.size() > 1) {
 
   67            auto scores = scoring_function(invalid_variables, t_node);
 
   68            selected_variable = get_argmax_score(scores);
 
   71        return create_child_nodes_for_selected_variable(t_node, selected_variable);
 
   74    [[nodiscard]] 
const std::list<Var>& branching_candidates()
 const { 
return m_branching_candidates; }
 
   78          m_branching_candidates(std::move(t_branching_candidates)) {
 
   83    std::list<Var> get_invalid_variables(
const PrimalPoint& t_primal_solution) {
 
   85        std::list<Var> result;
 
   87        for (
const auto& var : m_branching_candidates) {
 
   88            if (
const double value = t_primal_solution.get(var) ; !is_integer(value, 
Tolerance::Integer)) {
 
   89                result.emplace_back(var);
 
   96    Var get_argmax_score(
const std::list<std::pair<Var, double>>& t_scores) {
 
   98        if (t_scores.empty()) {
 
   99            throw Exception(
"VariableScoringFunction returned an empty list.");
 
  102        double max = std::numeric_limits<double>::lowest();
 
  103        std::optional<Var> argmax;
 
  105        for (
const auto& [var, score] : t_scores) {
 
  112        if (!argmax.has_value()) {
 
  113            throw Exception(
"Could not compute argmax of scores while searching for branching variable.");
 
  116        return argmax.value();