Skip to content

Commit 5e2d000

Browse files
committed
optimize entrry recalculation
Signed-off-by: Lev Nachmanson <[email protected]>
1 parent ecfbdbb commit 5e2d000

File tree

1 file changed

+71
-37
lines changed

1 file changed

+71
-37
lines changed

src/math/lp/dioph_eq.cpp

Lines changed: 71 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,12 @@ namespace lp {
487487
// m_changed_columns are the columns that just became fixed, or those that just stopped being fixed.
488488
// If such a column appears in an entry it has to be recalculated.
489489
indexed_uint_set m_changed_columns;
490-
indexed_uint_set m_changed_terms; // a term is defined by its column j, as in lar_solver.get_term(j)
490+
enum class term_status{
491+
no_change,
492+
change, // need to find changed rows depending on the term
493+
bound_change // need to tighten the term
494+
};
495+
std_vector<term_status> m_changed_terms;
491496
indexed_uint_set m_tightened_columns; // the column that got tightened by the tigthening phase,
492497
// m_column_to_terms[j] is the set of all k such lra.get_term(k) depends on j
493498
std::unordered_map<unsigned, std::unordered_set<unsigned>> m_columns_to_terms;
@@ -732,30 +737,37 @@ namespace lp {
732737
std_vector<constraint_index> m_explanation_of_branches;
733738
void add_term_callback(const lar_term* t) {
734739
unsigned j = t->j();
735-
TRACE("dioph_eq", tout << "term column t->j():" << j << std::endl; lra.print_term(*t, tout) << std::endl;);
740+
TRACE("dio", tout << "term column t->j():" << j << std::endl; lra.print_term(*t, tout) << std::endl;);
736741
if (!lra.column_is_int(j)) {
737-
TRACE("dioph_eq", tout << "ignored a non-integral column" << std::endl;);
742+
TRACE("dio", tout << "ignored a non-integral column" << std::endl;);
738743
return;
739744
}
740745

741-
CTRACE("dioph_eq", !lra.column_has_term(j), tout << "added term that is not associated with a column yet" << std::endl;);
746+
CTRACE("dio", !lra.column_has_term(j), tout << "added term that is not associated with a column yet" << std::endl;);
742747

743748
if (!lia.column_is_int(t->j())) {
744-
TRACE("dioph_eq", tout << "not all vars are integrall\n";);
749+
TRACE("dio", tout << "not all vars are integrall\n";);
745750
return;
746751
}
747752
m_added_terms.push_back(t);
748-
m_changed_terms.insert(t->j());
753+
mark_term_change(t->j());
749754
auto undo = undo_add_term(*this, t);
750755
lra.trail().push(undo);
751756
}
752757

758+
void mark_term_change(unsigned j) {
759+
TRACE("dio", tout << "marked term change j:" << j << std::endl;);
760+
if (j >= m_changed_terms.size())
761+
m_changed_terms.resize(j + 1, term_status::no_change);
762+
m_changed_terms[j] = term_status::change;
763+
}
764+
753765
void update_column_bound_callback(unsigned j) {
754766
if (!lra.column_is_int(j) || !lra.column_is_fixed(j))
755767
return;
768+
TRACE("dio", tout << "j:" << j << "\n"; lra.print_column_info(j, tout););
756769
m_changed_columns.insert(j);
757-
auto undo = undo_fixed_column(*this, j);
758-
lra.trail().push(undo);
770+
lra.trail().push(undo_fixed_column(*this, j));
759771
}
760772

761773
public:
@@ -782,7 +794,7 @@ namespace lp {
782794
}
783795

784796
void register_columns_to_term(const lar_term& t) {
785-
TRACE("dioph_eq", tout << "register term:"; lra.print_term(t, tout); tout << ", t.j()=" << t.j() << std::endl;);
797+
TRACE("dio_reg", tout << "register term:"; lra.print_term(t, tout); tout << ", t.j()=" << t.j() << std::endl;);
786798
for (const auto& p : t.ext_coeffs()) {
787799
auto it = m_columns_to_terms.find(p.var());
788800
TRACE("dio_reg", tout << "register p.var():" << p.var() << "->" << t.j() << std::endl;);
@@ -799,11 +811,9 @@ namespace lp {
799811
}
800812
// the term has form sum(a_i*x_i) - t.j() = 0,
801813
void fill_entry(const lar_term& t) {
802-
TRACE("dioph_eq", print_lar_term_L(t, tout) << std::endl;);
803814
unsigned entry_index = (unsigned)m_e_matrix.row_count();
804815
m_sum_of_fixed.push_back(mpq(0));
805-
mpq& e = m_sum_of_fixed.back();
806-
SASSERT(m_l_matrix.row_count() == m_e_matrix.row_count());
816+
mpq& fixed_sum = m_sum_of_fixed.back();
807817
// fill m_l_matrix row
808818
m_l_matrix.add_row();
809819
// todo: consider to compress variables t.j() by using a devoted var_register for term columns
@@ -812,21 +822,21 @@ namespace lp {
812822
// fill E-entry
813823
m_e_matrix.add_row();
814824

815-
SASSERT(m_e_matrix.row_count() == m_e_matrix.row_count());
825+
SASSERT(m_sum_of_fixed.size() == m_l_matrix.row_count() && m_e_matrix.row_count() == m_e_matrix.row_count());
816826

817827
for (const auto& p : t.ext_coeffs()) {
818828
SASSERT(p.coeff().is_int());
819829
if (is_fixed(p.var()))
820-
e += p.coeff() * lia.lower_bound(p.var()).x;
830+
fixed_sum += p.coeff() * lia.lower_bound(p.var()).x;
821831
else {
822832
unsigned lj = add_var(p.var());
823833
m_e_matrix.add_columns_up_to(lj);
824834
m_e_matrix.add_new_element(entry_index, lj, p.coeff());
825835
}
826836
}
827-
TRACE("dioph_eq", print_entry(entry_index, tout) << std::endl;);
828837
subs_entry(entry_index);
829838
SASSERT(entry_invariant(entry_index));
839+
TRACE("dio", print_entry(entry_index, tout) << std::endl;);
830840
}
831841
void subs_entry(unsigned ei) {
832842
if (ei >= m_e_matrix.row_count()) return;
@@ -836,7 +846,10 @@ namespace lp {
836846
if (can_substitute(p.var()))
837847
m_q.push(p.var());
838848
}
839-
if (m_q.size() == 0) return;
849+
if (m_q.size() == 0) {
850+
TRACE("dio", tout << "nothing to subst on ei:" << ei << "\n";);
851+
return;
852+
}
840853
substitute_on_q(ei);
841854
SASSERT(entry_invariant(ei));
842855
}
@@ -908,10 +921,10 @@ namespace lp {
908921
}
909922

910923
void recalculate_entry(unsigned ei) {
911-
TRACE("dioph_eq", print_entry(ei, tout) << std::endl;);
912-
mpq& c = m_sum_of_fixed[ei];
913-
c = mpq(0);
914-
open_l_term_to_espace(ei, c);
924+
TRACE("dio", print_entry(ei, tout) << std::endl;);
925+
mpq& fixed_sum = m_sum_of_fixed[ei];
926+
fixed_sum = mpq(0);
927+
open_l_term_to_espace(ei, fixed_sum);
915928
clear_e_row(ei);
916929
mpq denom(1);
917930
for (const auto& p : m_espace.m_data) {
@@ -923,7 +936,7 @@ namespace lp {
923936
}
924937
}
925938
if (!denom.is_one()) {
926-
c *= denom;
939+
fixed_sum *= denom;
927940
m_l_matrix.multiply_row(ei, denom);
928941
m_e_matrix.multiply_row(ei, denom);
929942
}
@@ -938,12 +951,12 @@ namespace lp {
938951
const auto it = m_columns_to_terms.find(j);
939952
if (it != m_columns_to_terms.end())
940953
for (unsigned k : it->second) {
941-
m_changed_terms.insert(k);
954+
mark_term_change(k);
942955
}
943956
if (!m_var_register.external_is_used(j))
944957
continue;
945958
for (const auto& p : m_e_matrix.column(this->lar_solver_to_local(j))) {
946-
m_changed_rows.insert(p.var()); // TODO: is it necessary?
959+
m_changed_rows.insert(p.var());
947960
}
948961
}
949962
}
@@ -984,10 +997,17 @@ namespace lp {
984997

985998
void process_changed_columns(std_vector<unsigned> &f_vector) {
986999
find_changed_terms_and_more_changed_rows();
987-
for (unsigned j : m_changed_terms) {
988-
if (j >= m_l_matrix.column_count()) continue;
989-
for (const auto& cs : m_l_matrix.column(j)) {
990-
m_changed_rows.insert(cs.var());
1000+
for (unsigned j = 0; j < m_changed_terms.size(); j++) {
1001+
term_status t = m_changed_terms[j];
1002+
if (t != term_status::change) {
1003+
TRACE("dio", tout << "went on continue\n";);
1004+
continue;
1005+
}
1006+
m_changed_terms[j] = term_status::bound_change; // prepare for tightening
1007+
if (j < m_l_matrix.column_count()) {
1008+
for (const auto& cs : m_l_matrix.column(j)) {
1009+
m_changed_rows.insert(cs.var());
1010+
}
9911011
}
9921012
}
9931013

@@ -1366,14 +1386,14 @@ namespace lp {
13661386
lia_move tighten_terms_with_S() {
13671387
// Copy changed terms to another vector for sorting
13681388
std_vector<unsigned> sorted_changed_terms;
1369-
std_vector<unsigned> cleanup;
13701389
m_tightened_columns.reset();
1371-
for (unsigned j : m_changed_terms) {
1390+
for (unsigned j = 0; j < m_changed_terms.size(); j++) {
1391+
if (m_changed_terms[j] == term_status::no_change) continue;
13721392
if (j >= lra.column_count() ||
13731393
!lra.column_has_term(j) ||
13741394
lra.column_is_free(j) ||
13751395
!lia.column_is_int(j)) {
1376-
cleanup.push_back(j);
1396+
unmark_changed_term(j);
13771397
continue;
13781398
}
13791399
sorted_changed_terms.push_back(j);
@@ -1392,18 +1412,19 @@ namespace lp {
13921412
// print_bounds(tout);
13931413
);
13941414
for (unsigned j : sorted_changed_terms) {
1395-
m_changed_terms.remove(j);
1415+
unmark_changed_term(j);
13961416
r = tighten_bounds_for_term_column(j);
13971417
if (r != lia_move::undef) {
13981418
break;
13991419
}
14001420
}
1401-
for (unsigned j : cleanup) {
1402-
m_changed_terms.remove(j);
1403-
}
14041421
return r;
14051422
}
14061423

1424+
void unmark_changed_term(unsigned j) {
1425+
m_changed_terms[j] = term_status::no_change;
1426+
}
1427+
14071428
term_o create_term_from_espace() const {
14081429
term_o t;
14091430
for (const auto& p : m_espace.m_data) {
@@ -1754,7 +1775,7 @@ namespace lp {
17541775
}
17551776
return lia_move::conflict;
17561777
}
1757-
TRACE("dio", print_S(tout));
1778+
TRACE("dio_s", print_S(tout));
17581779

17591780
return lia_move::undef;
17601781
}
@@ -2286,6 +2307,20 @@ namespace lp {
22862307
mpq ls_val = get_term_value(ls);
22872308
if (!ls_val.is_zero()) {
22882309
std::cout << "ls_val is not zero\n";
2310+
enable_trace("dio");
2311+
TRACE("dio", {
2312+
tout << "get_term_from_entry(" << ei << "):";
2313+
print_term_o(get_term_from_entry(ei), tout) << std::endl;
2314+
tout << "ls:";
2315+
print_term_o(ls, tout) << std::endl;
2316+
tout << "e.m_l:";
2317+
print_lar_term_L(l_term_from_row(ei), tout) << std::endl;
2318+
tout << "open_ml(e.m_l):";
2319+
print_lar_term_L(open_ml(l_term_from_row(ei)), tout) << std::endl;
2320+
tout << "rs:";
2321+
print_term_o(fix_vars(open_ml(m_l_matrix.m_rows[ei])), tout) << std::endl;
2322+
});
2323+
22892324
return false;
22902325
}
22912326
bool ret = ls == fix_vars(open_ml(m_l_matrix.m_rows[ei]));
@@ -2296,8 +2331,7 @@ namespace lp {
22962331
tout << "get_term_from_entry(" << ei << "):";
22972332
print_term_o(get_term_from_entry(ei), tout) << std::endl;
22982333
tout << "ls:";
2299-
print_term_o(remove_fresh_vars(get_term_from_entry(ei)), tout)
2300-
<< std::endl;
2334+
print_term_o(ls, tout) << std::endl;
23012335
tout << "e.m_l:";
23022336
print_lar_term_L(l_term_from_row(ei), tout) << std::endl;
23032337
tout << "open_ml(e.m_l):";

0 commit comments

Comments
 (0)