Skip to content

Commit 61beec8

Browse files
authored
Fix infinite average pseudocost + Handle numerical issues in strong branching (#678)
If the LP relaxation when branching on a fractional variable in the strong branching do not lead to a optimal solution and the iteration limit is not reach, then the corresponding pseudocost is set to infinite. This ignore any issue in the dual simplex and cause the pseudocost average to also be infinite. This PR properly handle numerical issues in the dual simplex in strong branching and exclude infinite pseudocost to be included in the average. Not critical for 25.12. Authors: - Nicolas L. Guidotti (https://github.com/nguidotti) Approvers: - Chris Maes (https://github.com/chris-maes) URL: #678
1 parent e3892d3 commit 61beec8

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

cpp/src/dual_simplex/pseudo_costs.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ void strong_branch_helper(i_t start,
7070
iter,
7171
child_edge_norms);
7272

73-
f_t obj = std::numeric_limits<f_t>::infinity();
73+
f_t obj = std::numeric_limits<f_t>::quiet_NaN();
7474
if (status == dual::status_t::DUAL_UNBOUNDED) {
7575
// LP was infeasible
76+
obj = std::numeric_limits<f_t>::infinity();
7677
} else if (status == dual::status_t::OPTIMAL || status == dual::status_t::ITERATION_LIMIT) {
7778
obj = compute_objective(child_problem, solution.x);
7879
} else {
@@ -227,11 +228,17 @@ void pseudo_costs_t<i_t, f_t>::initialized(i_t& num_initialized_down,
227228
for (i_t j = 0; j < n; j++) {
228229
if (pseudo_cost_num_down[j] > 0) {
229230
num_initialized_down++;
230-
pseudo_cost_down_avg += pseudo_cost_sum_down[j] / pseudo_cost_num_down[j];
231+
if (std::isfinite(pseudo_cost_sum_down[j])) {
232+
pseudo_cost_down_avg += pseudo_cost_sum_down[j] / pseudo_cost_num_down[j];
233+
}
231234
}
235+
232236
if (pseudo_cost_num_up[j] > 0) {
233237
num_initialized_up++;
234-
pseudo_cost_up_avg += pseudo_cost_sum_up[j] / pseudo_cost_num_up[j];
238+
239+
if (std::isfinite(pseudo_cost_sum_up[j])) {
240+
pseudo_cost_up_avg += pseudo_cost_sum_up[j] / pseudo_cost_num_up[j];
241+
}
235242
}
236243
}
237244
if (num_initialized_down > 0) {
@@ -317,14 +324,16 @@ void pseudo_costs_t<i_t, f_t>::update_pseudo_costs_from_strong_branching(
317324
for (i_t k = 0; k < fractional.size(); k++) {
318325
const i_t j = fractional[k];
319326
for (i_t branch = 0; branch < 2; branch++) {
320-
const f_t frac = branch == 0 ? root_soln[j] - std::floor(root_soln[j])
321-
: std::ceil(root_soln[j]) - root_soln[j];
322327
if (branch == 0) {
323328
f_t change_in_obj = strong_branch_down[k];
329+
if (std::isnan(change_in_obj)) { continue; }
330+
f_t frac = root_soln[j] - std::floor(root_soln[j]);
324331
pseudo_cost_sum_down[j] += change_in_obj / frac;
325332
pseudo_cost_num_down[j]++;
326333
} else {
327334
f_t change_in_obj = strong_branch_up[k];
335+
if (std::isnan(change_in_obj)) { continue; }
336+
f_t frac = std::ceil(root_soln[j]) - root_soln[j];
328337
pseudo_cost_sum_up[j] += change_in_obj / frac;
329338
pseudo_cost_num_up[j]++;
330339
}

0 commit comments

Comments
 (0)