Skip to content

Commit 972f801

Browse files
committed
throttle dio for big numbers
Signed-off-by: Lev Nachmanson <[email protected]>
1 parent 3e49d9f commit 972f801

File tree

6 files changed

+48
-25
lines changed

6 files changed

+48
-25
lines changed

src/math/lp/dioph_eq.cpp

+41-22
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ namespace lp {
343343
return out;
344344
}
345345

346-
bool m_has_non_integral_term = false;
346+
bool m_some_terms_are_ignored = false;
347347
std_vector<mpq> m_sum_of_fixed;
348348
// we have to use m_var_register because of the fresh variables: otherwise they clash with the existing lar_solver column indices
349349
var_register m_var_register;
@@ -779,26 +779,29 @@ namespace lp {
779779
std_vector<variable_branch_stats> m_branch_stats;
780780
std_vector<branch> m_branch_stack;
781781
std_vector<constraint_index> m_explanation_of_branches;
782-
bool term_has_big_number(const lar_term* t) const {
783-
for (const auto& p : *t)
782+
bool term_has_big_number(const lar_term& t) const {
783+
for (const auto& p : t)
784784
if (p.coeff().is_big())
785785
return true;
786786
return false;
787787
}
788+
789+
bool ignore_big_nums() const { return lra.settings().dio_ignore_big_nums(); }
790+
788791
void add_term_callback(const lar_term* t) {
789792
unsigned j = t->j();
790793
TRACE("dio", tout << "term column t->j():" << j << std::endl; lra.print_term(*t, tout) << std::endl;);
791794
if (!lra.column_is_int(j)) {
792795
TRACE("dio", tout << "ignored a non-integral column" << std::endl;);
793-
m_has_non_integral_term = true;
796+
m_some_terms_are_ignored = true;
794797
return;
795798
}
796799

797800
CTRACE("dio", !lra.column_has_term(j), tout << "added term that is not associated with a column yet" << std::endl;);
798801

799-
if (term_has_big_number(t)) {
802+
if (ignore_big_nums() && term_has_big_number(*t)) {
800803
TRACE("dio", tout << "term_has_big_number\n";);
801-
m_has_non_integral_term = true;
804+
m_some_terms_are_ignored = true;
802805
return;
803806
}
804807
m_added_terms.push_back(t);
@@ -815,11 +818,12 @@ namespace lp {
815818
void update_column_bound_callback(unsigned j) {
816819
if (!lra.column_is_int(j))
817820
return;
818-
if (lra.column_has_term(j) && !term_has_big_number(&lra.get_term(j)))
821+
if (lra.column_has_term(j) &&
822+
ignore_big_nums() && !term_has_big_number(lra.get_term(j)))
819823
m_terms_to_tighten.insert(j); // the boundary of the term has changed: we can be successful to tighten this term
820824
if (!lra.column_is_fixed(j))
821825
return;
822-
if (lra.get_lower_bound(j).x.is_big())
826+
if (ignore_big_nums() && lra.get_lower_bound(j).x.is_big())
823827
return;
824828
TRACE("dio", tout << "j:" << j << "\n"; lra.print_column_info(j, tout););
825829
m_changed_columns.insert(j);
@@ -1054,7 +1058,9 @@ namespace lp {
10541058
void process_changed_columns(std_vector<unsigned> &f_vector) {
10551059
find_changed_terms_and_more_changed_rows();
10561060
for (unsigned j: m_changed_terms) {
1057-
SASSERT(!term_has_big_number(&lra.get_term(j)));
1061+
if (j >= lra.column_count())
1062+
continue;
1063+
SASSERT(!ignore_big_nums() || !term_has_big_number(lra.get_term(j)));
10581064
m_terms_to_tighten.insert(j);
10591065
if (j < m_l_matrix.column_count()) {
10601066
for (const auto& cs : m_l_matrix.column(j)) {
@@ -1346,10 +1352,13 @@ namespace lp {
13461352
unsigned best_var = UINT_MAX;
13471353
size_t min_new_vars = std::numeric_limits<size_t>::max();
13481354
unsigned num_candidates = 0;
1349-
1355+
std::vector<unsigned> to_remove;
13501356
for (unsigned j : q.m_q) {
13511357
size_t new_vars = 0;
1352-
if (!m_espace.has(j)) continue;
1358+
if (!m_espace.has(j)) {
1359+
to_remove.push_back(j);
1360+
continue;
1361+
}
13531362
if (m_k2s.has_key(j)) {
13541363
unsigned ei = m_k2s[j]; // entry index for substitution
13551364
for (const auto& p : m_e_matrix.m_rows[ei])
@@ -1377,6 +1386,10 @@ namespace lp {
13771386
if (best_var != UINT_MAX)
13781387
q.remove(best_var);
13791388

1389+
for (unsigned j: to_remove)
1390+
q.remove(j);
1391+
1392+
13801393
return best_var;
13811394
}
13821395

@@ -1544,25 +1557,31 @@ namespace lp {
15441557

15451558
// We will have lar_t, and let j is lar_t.j(), the term column.
15461559
// In the m_espace we have lar_t. The result of open_ml((1*j)) is lar_t - (1, j).
1547-
// So we have "equality" m_espace = open(m_lspace) + (1*lar_t.j())
1548-
void init_substitutions(const lar_term& lar_t, protected_queue& q) {
1560+
// So we have "equality" m_espace = open(m_lspace) + (1*lar_t.j())
1561+
// return false iff seen a big number and dio_ignore_big_nums() is true
1562+
bool init_substitutions(const lar_term& lar_t, protected_queue& q) {
15491563
m_espace.clear();
15501564
m_c = mpq(0);
15511565
m_lspace.clear();
15521566
m_lspace.add(mpq(1), lar_t.j());
15531567
SASSERT(get_extended_term_value(lar_t).is_zero());
15541568
for (const auto& p : lar_t) {
15551569
if (is_fixed(p.j())) {
1556-
m_c += p.coeff() * lia.lower_bound(p.j()).x;
1570+
const mpq& b = lia.lower_bound(p.j()).x;
1571+
if (ignore_big_nums() && b.is_big())
1572+
return false;
1573+
m_c += p.coeff() * b;
15571574
}
15581575
else {
15591576
unsigned lj = lar_solver_to_local(p.j());
1577+
SASSERT(!p.coeff().is_big());
15601578
m_espace.add(p.coeff(), lj);;
15611579
if (can_substitute(lj))
15621580
q.push(lj);
15631581
}
15641582
}
15651583
SASSERT(subs_invariant(lar_t.j()));
1584+
return true;
15661585
}
15671586

15681587
unsigned lar_solver_to_local(unsigned j) const {
@@ -1584,8 +1603,6 @@ namespace lp {
15841603

15851604
lia_move tighten_on_espace(unsigned j) {
15861605
mpq g = gcd_of_coeffs(m_espace.m_data, true);
1587-
TRACE("dio", tout << "after process_q_with_S\nt:"; print_term_o(create_term_from_espace(), tout) << std::endl; tout << "g:" << g << std::endl;);
1588-
15891606
if (g.is_one())
15901607
return lia_move::undef;
15911608
if (g.is_zero()) {
@@ -1623,7 +1640,8 @@ namespace lp {
16231640
lra.print_column_info(p.var(), tout);
16241641
}
16251642
);
1626-
init_substitutions(lra.get_term(j), q);
1643+
if (!init_substitutions(lra.get_term(j), q))
1644+
return lia_move::undef;
16271645

16281646
TRACE("dio", tout << "t:";
16291647
tout << "m_espace:";
@@ -2218,6 +2236,8 @@ namespace lp {
22182236
for (unsigned k = 0; k < lra.terms().size(); k++) {
22192237
const lar_term* t = lra.terms()[k];
22202238
if (!lia.column_is_int(t->j())) continue;
2239+
if (ignore_big_nums() && term_has_big_number(*t))
2240+
continue;
22212241
SASSERT(t->j() != UINT_MAX);
22222242
for (const auto& p : (*t).ext_coeffs()) {
22232243
unsigned j = p.var();
@@ -2288,7 +2308,6 @@ namespace lp {
22882308
public:
22892309
lia_move check() {
22902310
lra.stats().m_dio_calls++;
2291-
std::cout << "check" << std::endl;
22922311
TRACE("dio", tout << lra.stats().m_dio_calls << std::endl;);
22932312
std_vector<unsigned> f_vector;
22942313
lia_move ret;
@@ -2778,8 +2797,8 @@ namespace lp {
27782797
// needed for the template bound_analyzer_on_row.h
27792798
const lar_solver& lp() const { return lra; }
27802799
lar_solver& lp() {return lra;}
2781-
bool has_non_integral_term() const {
2782-
return m_has_non_integral_term;
2800+
bool some_terms_are_ignored() const {
2801+
return m_some_terms_are_ignored;
27832802
}
27842803
};
27852804
// Constructor definition
@@ -2798,8 +2817,8 @@ namespace lp {
27982817
m_imp->explain(ex);
27992818
}
28002819

2801-
bool dioph_eq::has_non_integral_term() const {
2802-
return m_imp->has_non_integral_term();
2820+
bool dioph_eq::some_terms_are_ignored() const {
2821+
return m_imp->some_terms_are_ignored();
28032822
}
28042823

28052824

src/math/lp/dioph_eq.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ namespace lp {
3030
~dioph_eq();
3131
lia_move check();
3232
void explain(lp::explanation&);
33-
bool has_non_integral_term() const;
33+
bool some_terms_are_ignored() const;
3434
};
3535
}

src/math/lp/int_solver.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,7 @@ namespace lp {
188188

189189
bool should_gomory_cut() {
190190
bool dio_allows_gomory = !settings().dio_eqs() || settings().dio_enable_gomory_cuts() ||
191-
m_dio.has_non_integral_term();
192-
std::cout << "should_gomory_cut:" << dio_allows_gomory << std::endl;
191+
m_dio.some_terms_are_ignored();
193192
return dio_allows_gomory && m_number_of_calls % settings().m_int_gomory_cut_period == 0;
194193
}
195194

src/math/lp/lp_params_helper.pyg

+1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ def_module_params(module_name='lp',
66
('dio_branching_period', UINT, 100, 'Period of calling branching on undef in Diophantine handler'),
77
('dio_cuts_enable_gomory', BOOL, False, 'enable Gomory cuts together with Diophantine cuts, only relevant when dioph_eq is true'),
88
('dio_cuts_enable_hnf', BOOL, True, 'enable hnf cuts together with Diophantine cuts, only relevant when dioph_eq is true'),
9+
('dio_ignore_big_nums', BOOL, True, 'Ignore the terms with big numbers in the Diophantine handler, only relevant when dioph_eq is true'),
910
))
1011

src/math/lp/lp_settings.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ void lp::lp_settings::updt_params(params_ref const& _p) {
3838
m_dio_enable_gomory_cuts = lp_p.dio_cuts_enable_gomory();
3939
m_dio_enable_hnf_cuts = lp_p.dio_cuts_enable_hnf();
4040
m_dio_branching_period = lp_p.dio_branching_period();m_dump_bound_lemmas = p.arith_dump_bound_lemmas();
41+
m_dio_ignore_big_nums = lp_p.dio_ignore_big_nums();
4142
}

src/math/lp/lp_settings.h

+3
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ struct lp_settings {
261261
unsigned m_dio_branching_period = 100; // do branching rarely
262262
unsigned m_dio_report_branch_with_term_tigthening_period = 10000000; // period of reporting the branch with term tigthening
263263
bool m_dump_bound_lemmas = false;
264+
bool m_dio_ignore_big_nums = false;
265+
264266
public:
265267
bool print_external_var_name() const { return m_print_external_var_name; }
266268
bool propagate_eqs() const { return m_propagate_eqs;}
@@ -272,6 +274,7 @@ struct lp_settings {
272274
bool dio_enable_gomory_cuts() const { return m_dio_eqs && m_dio_enable_gomory_cuts; }
273275
bool dio_enable_hnf_cuts() const { return m_dio_eqs && m_dio_enable_hnf_cuts; }
274276
unsigned dio_branching_period() const { return m_dio_branching_period; }
277+
bool dio_ignore_big_nums() const { return m_dio_ignore_big_nums; }
275278
void set_random_seed(unsigned s) { m_rand.set_seed(s); }
276279
unsigned dio_report_branch_with_term_tigthening_period() const { return m_dio_report_branch_with_term_tigthening_period; }
277280
bool bound_progation() const {

0 commit comments

Comments
 (0)