45 const std::vector<VariableBoundChange>& bound_changes,
46 const IntegerValue obj_bound_improvement) {
47 DCHECK_GE(obj_bound_improvement, 0);
48 if (obj_bound_improvement == IntegerValue(0))
return;
50 const double epsilon = 1e-6;
51 for (
const auto [
var, lb_change] : bound_changes) {
52 if (lb_change == IntegerValue(0))
continue;
54 if (
var >= pseudo_costs_.size()) {
57 is_relevant_.
resize(new_size,
false);
58 scores_.
resize(new_size, 0.0);
62 pseudo_costs_[
var].AddData(
ToDouble(obj_bound_improvement) /
66 const IntegerVariable negative_var =
NegationOf(positive_var);
67 const int64_t count = pseudo_costs_[positive_var].NumRecords() +
68 pseudo_costs_[negative_var].NumRecords();
69 if (count >= parameters_.pseudo_cost_reliability_threshold()) {
70 scores_[positive_var] = std::max(
GetCost(positive_var), epsilon) *
71 std::max(
GetCost(negative_var), epsilon);
73 if (!is_relevant_[positive_var]) {
74 is_relevant_[positive_var] =
true;
75 relevant_variables_.push_back(positive_var);
86 double best_score = -std::numeric_limits<double>::infinity();
91 for (
const IntegerVariable positive_var : relevant_variables_) {
92 const IntegerValue lb = integer_trail_->
LowerBound(positive_var);
93 const IntegerValue ub = integer_trail_->
UpperBound(positive_var);
94 if (lb >= ub)
continue;
95 if (scores_[positive_var] > best_score) {
96 chosen_var = positive_var;
97 best_score = scores_[positive_var];