Skip to content

Commit a3529a0

Browse files
committed
create bounds for gomory cuts with big numbers
1 parent af76912 commit a3529a0

File tree

1 file changed

+23
-22
lines changed

1 file changed

+23
-22
lines changed

src/math/lp/gomory.cpp

+23-22
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ struct create_cut {
3939
#if SMALL_CUTS
4040
mpq m_abs_max, m_big_number;
4141
#endif
42-
int m_polarity;
43-
bool m_found_big;
42+
int m_polarity;
43+
bool m_found_big;
44+
u_dependency* m_dep;
4445

4546
const impq & get_value(unsigned j) const { return lia.get_value(j); }
4647
bool is_int(unsigned j) const { return lia.column_is_int(j) || (lia.is_fixed(j) &&
@@ -330,6 +331,10 @@ struct create_cut {
330331
if (some_int_columns)
331332
simplify_inequality();
332333

334+
m_dep = nullptr;
335+
for (auto c : *m_ex)
336+
m_dep = lia.lra.join_deps(lia.lra.dep_manager().mk_leaf(c.ci()), m_dep);
337+
333338
TRACE("gomory_cut", print_linear_combination_of_column_indices_only(m_t.coeffs_as_vector(), tout << "gomory cut: "); tout << " >= " << m_k << std::endl;);
334339
TRACE("gomory_cut_detail", dump_cut_and_constraints_as_smt_lemma(tout);
335340
lia.lra.display(tout));
@@ -512,10 +517,10 @@ struct create_cut {
512517

513518

514519
lia_move gomory::get_gomory_cuts(unsigned num_cuts) {
515-
struct cut_result {explanation ex; lar_term t; mpq k; int polarity; lpvar j;};
520+
struct cut_result {u_dependency *dep; lar_term t; mpq k; int polarity; lpvar j;};
516521
vector<cut_result> big_cuts;
517-
struct polar_pair {int polarity; lpvar j; u_dependency *dep;};
518-
vector<polar_pair> polar_vars;
522+
struct polar_pair {int polarity; u_dependency *dep;};
523+
std::unordered_map<lpvar, polar_pair> polar_vars;
519524
unsigned_vector columns_for_cuts = gomory_select_int_infeasible_vars(num_cuts);
520525

521526
// define inline helper functions
@@ -524,15 +529,12 @@ struct create_cut {
524529
return all_of(t, [&](auto ci) { return ci.coeff().is_small(); });
525530
};
526531
auto add_cut = [&](cut_result const& cr) {
527-
u_dependency* dep = nullptr;
528-
for (auto c : cr.ex)
529-
dep = lra.join_deps(lra.dep_manager().mk_leaf(c.ci()), dep);
532+
u_dependency* dep = cr.dep;
530533
lp::lpvar term_index = lra.add_term(cr.t.coeffs_as_vector(), UINT_MAX);
531534
term_index = lra.map_term_index_to_column_index(term_index);
532535
lra.update_column_type_and_bound(term_index,
533536
lp::lconstraint_kind::GE,
534-
lia.m_k, dep);
535-
return dep;
537+
lia.m_k, dep);
536538
};
537539
auto _check_feasible = [&](void) {
538540
lra.find_feasible_solution();
@@ -552,17 +554,16 @@ struct create_cut {
552554

553555
if (r != lia_move::cut)
554556
continue;
555-
cut_result cr = {*lia.m_ex, lia.m_t, lia.m_k, cc.m_polarity, j};
556-
557+
cut_result cr = {cc.m_dep, lia.m_t, lia.m_k, cc.m_polarity, j};
558+
if (abs(cr.polarity) == 1) // need to delay the update of the bounds for j in a polar case, because simplify_inequality relies on the old bounds
559+
polar_vars[j] = {cr.polarity, cc.m_dep};
560+
557561
if (!is_small_cut(lia.m_t)) {
558562
big_cuts.push_back(cr);
559563
continue;
560564
}
561565
has_small_cut = true;
562-
auto dep = add_cut(cr);
563-
if (abs(cr.polarity) == 1) // need to delay the update of the bounds for j in a polar case, because simplify_inequality relies on the old bounds
564-
polar_vars.push_back({cr.polarity, j, dep}); // todo : polarity for big cuts
565-
566+
add_cut(cr);
566567
if (lia.settings().get_cancel_flag())
567568
return lia_move::undef;
568569
}
@@ -581,12 +582,14 @@ struct create_cut {
581582
return lia_move::conflict;
582583
}
583584

585+
// this way we create bounds for the variables in polar cases even where the terms had big numbers
584586
for (auto const& p : polar_vars) {
585-
if (p.polarity == 1) {
586-
lra.update_column_type_and_bound(p.j, lp::lconstraint_kind::LE, floor(lra.get_column_value(p.j).x), p.dep);
587+
if (p.second.polarity == 1) {
588+
lra.update_column_type_and_bound(p.first, lp::lconstraint_kind::LE, floor(lra.get_column_value(p.first).x), p.second.dep);
587589
}
588-
else if (p.polarity == -1) {
589-
lra.update_column_type_and_bound(p.j, lp::lconstraint_kind::GE, ceil(lra.get_column_value(p.j).x), p.dep);
590+
else {
591+
SASSERT(p.second.polarity == -1);
592+
lra.update_column_type_and_bound(p.first, lp::lconstraint_kind::GE, ceil(lra.get_column_value(p.first).x), p.second.dep);
590593
}
591594
}
592595

@@ -598,8 +601,6 @@ struct create_cut {
598601

599602
if (has_small_cut || big_cuts.size())
600603
return lia_move::continue_with_check;
601-
602-
603604

604605
lra.move_non_basic_columns_to_bounds();
605606
return lia_move::undef;

0 commit comments

Comments
 (0)