3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-10-09 01:11:55 +00:00

solve send-more-money_lev.smt2

Signed-off-by: Lev Nachmanson <levnach@microsoft.com>

handle integer vars in random_update

Signed-off-by: Lev Nachmanson <levnach@microsoft.com>

call the assert in gomory_cut and branching to a correct place

Signed-off-by: Lev Nachmanson <levnach@microsoft.com>

fixes in goromy cut

Signed-off-by: Lev Nachmanson <levnach@microsoft.com>

disable x values tracking in random_update

Signed-off-by: Lev Nachmanson <levnach@microsoft.com>

more fixes in gomory cut

Signed-off-by: Lev Nachmanson <levnach@microsoft.com>

change in mk_bound by Nikolaj

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

fixes in gomory cut and setup

Signed-off-by: Lev Nachmanson <levnach@microsoft.com>

fixes in int_solver

Signed-off-by: Lev Nachmanson <levnach@microsoft.com>

change a printout

Signed-off-by: Lev Nachmanson <levnach@microsoft.com>

fix by Nikolaj in treating terms returned by int_solver

Signed-off-by: Lev Nachmanson <levnach@microsoft.com>

fix syntax

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

fix a free coefficient bug in bound propagaion and simplify gomory cut

Signed-off-by: Lev Nachmanson <levnach@microsoft.com>

avoid tracking pivoted rows during int_solver::check()
This commit is contained in:
Lev Nachmanson 2017-07-27 10:49:00 -07:00 committed by Lev Nachmanson
parent aba7dcab3e
commit db8f01894f
31 changed files with 894 additions and 767 deletions

View file

@ -81,9 +81,18 @@ class lar_solver : public column_namer {
indexed_vector<mpq> m_column_buffer;
public:
lar_core_solver m_mpq_lar_core_solver;
private:
std::function<void (unsigned)> m_tracker_of_x_change;
int_solver * m_int_solver;
public:
void set_int_solver(int_solver * int_slv) {
m_int_solver = int_slv;
}
int_solver * get_int_solver() {
return m_int_solver;
}
unsigned constraint_count() const;
const lar_base_constraint& get_constraint(unsigned ci) const;
std::function<void (unsigned, const impq&)> m_tracker_of_x_change;
int_set m_inf_int_set;
////////////////// methods ////////////////////////////////
static_matrix<mpq, numeric_pair<mpq>> & A_r() { return m_mpq_lar_core_solver.m_r_A;}
@ -94,6 +103,14 @@ public:
static bool valid_index(unsigned j){ return static_cast<int>(j) >= 0;}
bool column_is_int(unsigned j) const;
bool column_value_is_int(unsigned j) const {
return m_mpq_lar_core_solver.m_r_x[j].is_int();
}
const impq& get_column_value(unsigned j) const {
return m_mpq_lar_core_solver.m_r_x[j];
}
bool is_term(var_index j) const;
bool column_is_fixed(unsigned j) const;
public:
@ -134,87 +151,13 @@ public:
void clear();
lar_solver();
void set_propagate_bounds_on_pivoted_rows_mode(bool v);
void set_track_pivoted_rows(bool v);
bool get_track_pivoted_rows() const;
virtual ~lar_solver();
void print_implied_bound(const implied_bound& be, std::ostream & out) const {
out << "implied bound\n";
unsigned v = be.m_j;
if (is_term(v)) {
out << "it is a term number " << be.m_j << std::endl;
print_term(*m_orig_terms[be.m_j - m_terms_start_index], out);
}
else {
out << get_column_name(v);
}
out << " " << lconstraint_kind_string(be.kind()) << " " << be.m_bound << std::endl;
// for (auto & p : be.m_explanation) {
// out << p.first << " : ";
// print_constraint(p.second, out);
// }
// m_mpq_lar_core_solver.m_r_solver.print_column_info(be.m_j< m_terms_start_index? be.m_j : adjust_term_index(be.m_j), out);
out << "end of implied bound" << std::endl;
}
bool implied_bound_is_correctly_explained(implied_bound const & be, const vector<std::pair<mpq, unsigned>> & explanation) const {
std::unordered_map<unsigned, mpq> coeff_map;
auto rs_of_evidence = zero_of_type<mpq>();
unsigned n_of_G = 0, n_of_L = 0;
bool strict = false;
for (auto & it : explanation) {
mpq coeff = it.first;
constraint_index con_ind = it.second;
const auto & constr = *m_constraints[con_ind];
lconstraint_kind kind = coeff.is_pos() ? constr.m_kind : flip_kind(constr.m_kind);
register_in_map(coeff_map, constr, coeff);
if (kind == GT || kind == LT)
strict = true;
if (kind == GE || kind == GT) n_of_G++;
else if (kind == LE || kind == LT) n_of_L++;
rs_of_evidence += coeff*constr.m_right_side;
}
SASSERT(n_of_G == 0 || n_of_L == 0);
lconstraint_kind kind = n_of_G ? GE : (n_of_L ? LE : EQ);
if (strict)
kind = static_cast<lconstraint_kind>((static_cast<int>(kind) / 2));
if (!is_term(be.m_j)) {
if (coeff_map.size() != 1)
return false;
auto it = coeff_map.find(be.m_j);
if (it == coeff_map.end()) return false;
mpq ratio = it->second;
if (ratio < zero_of_type<mpq>()) {
kind = static_cast<lconstraint_kind>(-kind);
}
rs_of_evidence /= ratio;
} else {
const lar_term * t = m_orig_terms[adjust_term_index(be.m_j)];
const auto first_coeff = *t->m_coeffs.begin();
unsigned j = first_coeff.first;
auto it = coeff_map.find(j);
if (it == coeff_map.end())
return false;
mpq ratio = it->second / first_coeff.second;
for (auto & p : t->m_coeffs) {
it = coeff_map.find(p.first);
if (it == coeff_map.end())
return false;
if (p.second * ratio != it->second)
return false;
}
if (ratio < zero_of_type<mpq>()) {
kind = static_cast<lconstraint_kind>(-kind);
}
rs_of_evidence /= ratio;
rs_of_evidence += t->m_v * ratio;
}
return kind == be.kind() && rs_of_evidence == be.m_bound;
}
unsigned adjust_term_index(unsigned j) const;
void analyze_new_bounds_on_row(
unsigned row_index,
@ -707,32 +650,9 @@ public:
bool tableau_with_costs() const;
bool costs_are_used() const {
return m_settings.simplex_strategy() != simplex_strategy_enum::tableau_rows;
}
void change_basic_x_by_delta_on_column(unsigned j, const numeric_pair<mpq> & delta) {
if (use_tableau()) {
for (const auto & c : A_r().m_columns[j]) {
unsigned bj = m_mpq_lar_core_solver.m_r_basis[c.m_i];
m_mpq_lar_core_solver.m_r_x[bj] -= A_r().get_val(c) * delta;
if (tableau_with_costs()) {
m_basic_columns_with_changed_cost.insert(bj);
}
m_mpq_lar_core_solver.m_r_solver.update_column_in_inf_set(bj);
}
} else {
m_column_buffer.clear();
m_column_buffer.resize(A_r().row_count());
m_mpq_lar_core_solver.m_r_solver.solve_Bd(j, m_column_buffer);
for (unsigned i : m_column_buffer.m_index) {
unsigned bj = m_mpq_lar_core_solver.m_r_basis[i];
m_mpq_lar_core_solver.m_r_x[bj] -= m_column_buffer[i] * delta;
m_mpq_lar_core_solver.m_r_solver.update_column_in_inf_set(bj);
}
}
}
bool costs_are_used() const;
void change_basic_columns_dependend_on_a_given_nb_column(unsigned j, const numeric_pair<mpq> & delta);
void update_x_and_inf_costs_for_column_with_changed_bounds(unsigned j);
void detect_rows_with_changed_bounds_for_column(unsigned j) {
@ -1261,8 +1181,8 @@ public:
void clean_inf_set_of_r_solver_after_pop();
void shrink_explanation_to_minimum(vector<std::pair<mpq, constraint_index>> & explanation) const;
bool column_represents_row_in_tableau(unsigned j) {
return m_vars_to_ul_pairs()[j].m_i != static_cast<row_index>(-1);
bool column_value_is_integer(unsigned j) const {
return get_column_value(j).is_int();
}
bool column_is_real(unsigned j) const {
@ -1442,6 +1362,43 @@ bool model_is_int_feasible() const;
t = lar_term(pol_after_subs, v);
}
bool inf_int_set_is_correct_for_column(unsigned j) const {
if (m_inf_int_set.contains(j) != (column_is_int(j) && (!column_value_is_integer(j)))) {
TRACE("arith_int",
tout << "j= " << j <<
" inf_int_set().contains(j) = " << m_inf_int_set.contains(j) <<
", column_is_int(j) = " << column_is_int(j) <<
"\n column_value_is_integer(j) = " << column_value_is_integer(j) <<
", val = " << get_column_value(j) << std::endl;);
return false;
}
return true;
}
bool inf_int_set_is_correct() const {
if (!has_int_var())
return true;
for (unsigned j = 0; j < A_r().column_count(); j++) {
if (inf_int_set_is_correct_for_column(j) == false)
return false;
}
return true;
}
bool has_int_var() const;
void call_assignment_tracker(unsigned j) {
if (!var_is_int(j)) {
lp_assert(m_inf_int_set.contains(j) == false);
return;
}
if (m_mpq_lar_core_solver.m_r_x[j].is_int())
m_inf_int_set.erase(j);
else
m_inf_int_set.insert(j);
}
lar_core_solver & get_core_solver() { return m_mpq_lar_core_solver; }
};
}