3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 13:28:47 +00:00

updates to local search integration

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-03-02 11:23:06 -08:00
parent 40df1949f5
commit c6f943e4d6
4 changed files with 39 additions and 21 deletions

View file

@ -31,7 +31,6 @@ namespace sat {
m_vars.push_back(var_info()); m_vars.push_back(var_info());
best_solution.resize(num_vars() + 1, false); best_solution.resize(num_vars() + 1, false);
cur_solution.resize(num_vars() + 1, false);
m_index_in_unsat_stack.resize(num_constraints(), 0); m_index_in_unsat_stack.resize(num_constraints(), 0);
coefficient_in_ob_constraint.resize(num_vars() + 1, 0); coefficient_in_ob_constraint.resize(num_vars() + 1, 0);
@ -65,7 +64,7 @@ namespace sat {
void local_search::init_cur_solution() { void local_search::init_cur_solution() {
for (unsigned v = 0; v < num_vars(); ++v) { for (unsigned v = 0; v < num_vars(); ++v) {
cur_solution[v] = (m_rand() % 2 == 1); m_vars[v].m_value = ((unsigned)(m_rand() % 100) < m_vars[v].m_bias);
} }
} }
@ -88,7 +87,7 @@ namespace sat {
// figure out variables scores and slack_scores // figure out variables scores and slack_scores
void local_search::init_scores() { void local_search::init_scores() {
for (unsigned v = 0; v < num_vars(); ++v) { for (unsigned v = 0; v < num_vars(); ++v) {
bool is_true = cur_solution[v]; bool is_true = cur_solution(v);
int_vector& truep = m_vars[v].m_watch[is_true]; int_vector& truep = m_vars[v].m_watch[is_true];
int_vector& falsep = m_vars[v].m_watch[!is_true]; int_vector& falsep = m_vars[v].m_watch[!is_true];
for (unsigned i = 0; i < falsep.size(); ++i) { for (unsigned i = 0; i < falsep.size(); ++i) {
@ -162,11 +161,14 @@ namespace sat {
objective_value = 0; objective_value = 0;
for (i = 0; i < ob_constraint.size(); ++i) { for (i = 0; i < ob_constraint.size(); ++i) {
v = ob_constraint[i].var_id; v = ob_constraint[i].var_id;
if (cur_solution[v]) if (cur_solution(v))
objective_value += ob_constraint[i].coefficient; objective_value += ob_constraint[i].coefficient;
} }
if (objective_value > best_objective_value) { if (objective_value > best_objective_value) {
best_solution = cur_solution; best_solution.reset();
for (unsigned v = 0; v < num_vars(); ++v) {
best_solution.push_back(cur_solution(v));
}
best_objective_value = objective_value; best_objective_value = objective_value;
} }
} }
@ -174,7 +176,7 @@ namespace sat {
bool local_search::all_objectives_are_met() const { bool local_search::all_objectives_are_met() const {
for (unsigned i = 0; i < ob_constraint.size(); ++i) { for (unsigned i = 0; i < ob_constraint.size(); ++i) {
bool_var v = ob_constraint[i].var_id; bool_var v = ob_constraint[i].var_id;
if (!cur_solution[v]) return false; if (!cur_solution(v)) return false;
} }
return true; return true;
} }
@ -216,6 +218,9 @@ namespace sat {
m_vars[t.var()].m_watch[is_pos(t)].push_back(id); m_vars[t.var()].m_watch[is_pos(t)].push_back(id);
m_constraints.back().m_literals.push_back(t); m_constraints.back().m_literals.push_back(t);
} }
if (sz == 1 && k == 0) {
m_vars[c[0].var()].m_bias = c[0].sign() ? 0 : 100;
}
} }
local_search::local_search(solver& s) : local_search::local_search(solver& s) :
@ -354,7 +359,7 @@ namespace sat {
// tell the SAT solvers about the phase of variables. // tell the SAT solvers about the phase of variables.
if (m_par && tries % 10 == 0) { if (m_par && tries % 10 == 0) {
m_par->set_phase(*this); m_par->get_phase(*this);
} }
} }
@ -373,6 +378,7 @@ namespace sat {
result = l_undef; result = l_undef;
} }
IF_VERBOSE(1, verbose_stream() << "(sat-local-search " << result << ")\n";); IF_VERBOSE(1, verbose_stream() << "(sat-local-search " << result << ")\n";);
IF_VERBOSE(2, display(verbose_stream()););
return result; return result;
} }
@ -394,13 +400,13 @@ namespace sat {
void local_search::flip(bool_var flipvar) void local_search::flip(bool_var flipvar)
{ {
// already changed truth value!!!! // already changed truth value!!!!
cur_solution[flipvar] = !cur_solution[flipvar]; m_vars[flipvar].m_value = !cur_solution(flipvar);
unsigned v; unsigned v;
int org_flipvar_score = score(flipvar); int org_flipvar_score = score(flipvar);
int org_flipvar_slack_score = slack_score(flipvar); int org_flipvar_slack_score = slack_score(flipvar);
bool flip_is_true = cur_solution[flipvar]; bool flip_is_true = cur_solution(flipvar);
int_vector& truep = m_vars[flipvar].m_watch[flip_is_true]; int_vector& truep = m_vars[flipvar].m_watch[flip_is_true];
int_vector& falsep = m_vars[flipvar].m_watch[!flip_is_true]; int_vector& falsep = m_vars[flipvar].m_watch[!flip_is_true];
@ -521,8 +527,8 @@ namespace sat {
bool local_search::tie_breaker_sat(bool_var v, bool_var best_var) { bool local_search::tie_breaker_sat(bool_var v, bool_var best_var) {
// most improvement on objective value // most improvement on objective value
int v_imp = cur_solution[v] ? -coefficient_in_ob_constraint.get(v, 0) : coefficient_in_ob_constraint.get(v, 0); int v_imp = cur_solution(v) ? -coefficient_in_ob_constraint.get(v, 0) : coefficient_in_ob_constraint.get(v, 0);
int b_imp = cur_solution[best_var] ? -coefficient_in_ob_constraint.get(best_var, 0) : coefficient_in_ob_constraint.get(best_var, 0); int b_imp = cur_solution(best_var) ? -coefficient_in_ob_constraint.get(best_var, 0) : coefficient_in_ob_constraint.get(best_var, 0);
// std::cout << v_imp << "\n"; // std::cout << v_imp << "\n";
// break tie 1: max imp // break tie 1: max imp
// break tie 2: conf_change // break tie 2: conf_change
@ -615,14 +621,14 @@ namespace sat {
void local_search::print_info(std::ostream& out) { void local_search::print_info(std::ostream& out) {
for (unsigned v = 0; v < num_vars(); ++v) { for (unsigned v = 0; v < num_vars(); ++v) {
out << "v" << v << "\t" << m_vars[v].m_neighbors.size() << '\t' << cur_solution[v] << '\t' << conf_change(v) << '\t' << score(v) << '\t' << slack_score(v) << '\n'; out << "v" << v << "\t" << m_vars[v].m_neighbors.size() << '\t' << cur_solution(v) << '\t' << conf_change(v) << '\t' << score(v) << '\t' << slack_score(v) << '\n';
} }
} }
void local_search::extract_model() { void local_search::extract_model() {
m_model.reset(); m_model.reset();
for (unsigned v = 0; v < num_vars(); ++v) { for (unsigned v = 0; v < num_vars(); ++v) {
m_model.push_back(cur_solution[v] ? l_true : l_false); m_model.push_back(cur_solution(v) ? l_true : l_false);
} }
} }
@ -631,6 +637,9 @@ namespace sat {
constraint const& c = m_constraints[i]; constraint const& c = m_constraints[i];
display(out, c); display(out, c);
} }
for (bool_var v = 0; v < num_vars(); ++v) {
display(out, v, m_vars[v]);
}
} }
void local_search::display(std::ostream& out, constraint const& c) const { void local_search::display(std::ostream& out, constraint const& c) const {
@ -638,7 +647,7 @@ namespace sat {
} }
void local_search::display(std::ostream& out, unsigned v, var_info const& vi) const { void local_search::display(std::ostream& out, unsigned v, var_info const& vi) const {
out << "v" << v << "\n"; out << "v" << v << " := " << (vi.m_value?"true":"false") << " bias: " << vi.m_bias << "\n";
} }
bool local_search::check_goodvar() { bool local_search::check_goodvar() {
@ -662,7 +671,9 @@ namespace sat {
} }
void local_search::set_phase(bool_var v, bool f) { void local_search::set_phase(bool_var v, bool f) {
std::cout << v << " " << f << "\n"; unsigned& bias = m_vars[v].m_bias;
if (f && bias < 100) bias++;
if (!f && bias > 0) bias--;
} }
} }

View file

@ -61,6 +61,9 @@ namespace sat {
}; };
struct var_info { struct var_info {
bool m_value; // current solution
unsigned m_bias; // bias for current solution in percentage.
// if bias is 0, then value is always false, if 100, then always true
bool m_conf_change; // whether its configure changes since its last flip bool m_conf_change; // whether its configure changes since its last flip
bool m_in_goodvar_stack; bool m_in_goodvar_stack;
int m_score; int m_score;
@ -70,6 +73,8 @@ namespace sat {
bool_var_vector m_neighbors; // neighborhood variables bool_var_vector m_neighbors; // neighborhood variables
int_vector m_watch[2]; int_vector m_watch[2];
var_info(): var_info():
m_value(true),
m_bias(50),
m_conf_change(true), m_conf_change(true),
m_in_goodvar_stack(false), m_in_goodvar_stack(false),
m_score(0), m_score(0),
@ -111,6 +116,8 @@ namespace sat {
inline int time_stamp(bool_var v) const { return m_vars[v].m_time_stamp; } inline int time_stamp(bool_var v) const { return m_vars[v].m_time_stamp; }
inline int cscc(bool_var v) const { return m_vars[v].m_cscc; } inline int cscc(bool_var v) const { return m_vars[v].m_cscc; }
inline void inc_cscc(bool_var v) { m_vars[v].m_cscc++; } inline void inc_cscc(bool_var v) { m_vars[v].m_cscc++; }
inline bool cur_solution(bool_var v) const { return m_vars[v].m_value; }
/* TBD: other scores */ /* TBD: other scores */
@ -118,9 +125,9 @@ namespace sat {
vector<constraint> m_constraints; vector<constraint> m_constraints;
inline bool is_pos(literal t) const { return !t.sign(); } inline bool is_pos(literal t) const { return !t.sign(); }
inline bool is_true(bool_var v) const { return cur_solution[v]; } inline bool is_true(bool_var v) const { return cur_solution(v); }
inline bool is_true(literal l) const { return cur_solution[l.var()] != l.sign(); } inline bool is_true(literal l) const { return cur_solution(l.var()) != l.sign(); }
inline bool is_false(literal l) const { return cur_solution[l.var()] == l.sign(); } inline bool is_false(literal l) const { return cur_solution(l.var()) == l.sign(); }
unsigned num_constraints() const { return m_constraints.size(); } // constraint index from 1 to num_constraint unsigned num_constraints() const { return m_constraints.size(); } // constraint index from 1 to num_constraint
@ -136,7 +143,6 @@ namespace sat {
int_vector goodvar_stack; int_vector goodvar_stack;
// information about solution // information about solution
bool_vector cur_solution; // !var: the current solution
int objective_value; // the objective function value corresponds to the current solution int objective_value; // the objective function value corresponds to the current solution
bool_vector best_solution; // !var: the best solution so far bool_vector best_solution; // !var: the best solution so far
int best_objective_value = -1; // the objective value corresponds to the best solution so far int best_objective_value = -1; // the objective value corresponds to the best solution so far

View file

@ -258,7 +258,7 @@ namespace sat {
} }
} }
void parallel::set_phase(local_search& s) { void parallel::get_phase(local_search& s) {
#pragma omp critical (par_solver) #pragma omp critical (par_solver)
{ {
for (unsigned i = 0; i < m_phase.size(); ++i) { for (unsigned i = 0; i < m_phase.size(); ++i) {
@ -273,7 +273,7 @@ namespace sat {
} }
} }
void parallel::get_phase(local_search& s) { void parallel::set_phase(local_search& s) {
#pragma omp critical (par_solver) #pragma omp critical (par_solver)
{ {
m_phase.reserve(s.num_vars(), 0); m_phase.reserve(s.num_vars(), 0);

View file

@ -963,6 +963,7 @@ namespace sat {
\brief import lemmas/units from parallel sat solvers. \brief import lemmas/units from parallel sat solvers.
*/ */
void solver::exchange_par() { void solver::exchange_par() {
if (m_par && at_search_lvl()) m_par->set_phase(*this);
if (m_par && at_base_lvl()) m_par->get_clauses(*this); if (m_par && at_base_lvl()) m_par->get_clauses(*this);
if (m_par && at_base_lvl()) { if (m_par && at_base_lvl()) {
// SASSERT(scope_lvl() == search_lvl()); // SASSERT(scope_lvl() == search_lvl());