39 bool nothing_to_recompute,
const UpdateRow& update_row,
40 Fractional cost_variation, std::vector<ColIndex>* bound_flip_candidates,
41 ColIndex* entering_col) {
49 DenseBitRow::ConstView can_decrease =
51 DenseBitRow::ConstView can_increase =
53 DenseBitRow::ConstView is_boxed =
64 const Fractional threshold = nothing_to_recompute
65 ? parameters_.minimum_acceptable_pivot()
66 : parameters_.ratio_test_zero_threshold();
68 Fractional variation_magnitude = std::abs(cost_variation) - threshold;
74 parameters_.harris_tolerance_ratio() *
76 Fractional harris_ratio = std::numeric_limits<Fractional>::max();
81 parameters_.degenerate_ministep_factor() *
89 const Fractional coeff = (cost_variation > 0.0) ? update_coefficients[
col]
90 : -update_coefficients[
col];
93 if (can_decrease[
col] && coeff > threshold) {
96 if (-reduced_costs[
col] > harris_ratio * coeff)
continue;
97 entry = ColWithRatio(
col, -reduced_costs[
col], coeff);
98 }
else if (can_increase[
col] && coeff < -threshold) {
101 if (reduced_costs[
col] > harris_ratio * -coeff)
continue;
102 entry = ColWithRatio(
col, reduced_costs[
col], -coeff);
108 std::max(minimum_delta / entry.coeff_magnitude,
109 entry.ratio + harris_tolerance / entry.coeff_magnitude);
110 if (hr < harris_ratio) {
114 if (
delta >= variation_magnitude) {
122 breakpoints_.push_back(entry);
130 std::make_heap(breakpoints_.begin(), breakpoints_.end());
141 harris_ratio = std::numeric_limits<Fractional>::max();
144 bound_flip_candidates->clear();
147 equivalent_entering_choices_.clear();
148 while (!breakpoints_.empty()) {
149 const ColWithRatio top = breakpoints_.front();
150 if (top.ratio > harris_ratio)
break;
163 if (variation_magnitude > 0.0) {
164 if (is_boxed[top.col]) {
165 variation_magnitude -=
167 if (variation_magnitude > 0.0) {
168 bound_flip_candidates->push_back(top.col);
169 std::pop_heap(breakpoints_.begin(), breakpoints_.end());
170 breakpoints_.pop_back();
179 if (top.coeff_magnitude >= best_coeff) {
188 harris_ratio = std::min(
190 std::max(minimum_delta / top.coeff_magnitude,
191 top.ratio + harris_tolerance / top.coeff_magnitude));
193 if (top.coeff_magnitude == best_coeff && top.ratio == step) {
195 equivalent_entering_choices_.push_back(top.col);
197 equivalent_entering_choices_.clear();
198 best_coeff = top.coeff_magnitude;
199 *entering_col = top.col;
209 std::pop_heap(breakpoints_.begin(), breakpoints_.end());
210 breakpoints_.pop_back();
214 if (!equivalent_entering_choices_.empty()) {
215 equivalent_entering_choices_.push_back(*entering_col);
217 equivalent_entering_choices_[std::uniform_int_distribution<int>(
218 0, equivalent_entering_choices_.size() - 1)(random_)];
220 stats_.num_perfect_ties.
Add(equivalent_entering_choices_.size()));
227 const Fractional pivot_limit = parameters_.minimum_acceptable_pivot();
228 if (best_coeff < pivot_limit && !bound_flip_candidates->empty()) {
231 for (
int i = bound_flip_candidates->size() - 1; i >= 0; --i) {
232 const ColIndex
col = (*bound_flip_candidates)[i];
233 if (std::abs(update_coefficients[
col]) < pivot_limit)
continue;
235 VLOG(1) <<
"Used bound flip to avoid bad pivot. Before: " << best_coeff
236 <<
" now: " << std::abs(update_coefficients[
col]);
246 bool nothing_to_recompute,
const UpdateRow& update_row,
247 Fractional cost_variation, ColIndex* entering_col) {
255 breakpoints_.clear();
258 const Fractional threshold = nothing_to_recompute
259 ? parameters_.minimum_acceptable_pivot()
260 : parameters_.ratio_test_zero_threshold();
264 parameters_.harris_tolerance_ratio() * dual_feasibility_tolerance;
266 parameters_.degenerate_ministep_factor() * dual_feasibility_tolerance;
268 const DenseBitRow::ConstView can_decrease =
270 const DenseBitRow::ConstView can_increase =
283 if (std::abs(update_coefficients[
col]) < threshold)
continue;
291 const Fractional coeff = (cost_variation > 0.0) ? update_coefficients[
col]
292 : -update_coefficients[
col];
296 if (std::abs(reduced_costs[
col]) <= dual_feasibility_tolerance) {
298 if (coeff > 0 && !can_decrease[
col])
continue;
299 if (coeff < 0 && !can_increase[
col])
continue;
304 if (coeff * reduced_costs[
col] > 0.0) {
305 breakpoints_.push_back(ColWithRatio(
307 std::max(minimum_delta,
308 harris_tolerance - std::abs(reduced_costs[
col])),
314 if (coeff * reduced_costs[
col] > 0.0)
continue;
318 breakpoints_.push_back(ColWithRatio(
319 col, std::abs(reduced_costs[
col]) + harris_tolerance, std::abs(coeff)));
323 std::make_heap(breakpoints_.begin(), breakpoints_.end());
334 Fractional improvement = std::abs(cost_variation);
335 while (!breakpoints_.empty()) {
336 const ColWithRatio top = breakpoints_.front();
339 DCHECK(top.ratio > step ||
340 (top.ratio == step && top.coeff_magnitude <= pivot_magnitude));
341 if (top.ratio > step && top.coeff_magnitude >= pivot_magnitude) {
342 *entering_col = top.col;
344 pivot_magnitude = top.coeff_magnitude;
346 improvement -= top.coeff_magnitude;
351 if (can_decrease[top.col] && can_increase[top.col] &&
352 std::abs(reduced_costs[top.col]) > threshold) {
353 improvement -= top.coeff_magnitude;
356 if (improvement <= 0.0)
break;
357 std::pop_heap(breakpoints_.begin(), breakpoints_.end());
358 breakpoints_.pop_back();