mirror of
https://github.com/Z3Prover/z3
synced 2025-08-17 08:42:15 +00:00
revise local search
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
22783a4bcb
commit
5fe40a25dc
3 changed files with 159 additions and 486 deletions
|
@ -36,6 +36,16 @@ namespace sat {
|
|||
local_search_mode m_mode;
|
||||
bool m_phase_sticky;
|
||||
bool m_dbg_flips;
|
||||
|
||||
friend class local_search;
|
||||
|
||||
void set_config(config const& cfg) {
|
||||
m_mode = cfg.m_local_search_mode;
|
||||
m_random_seed = cfg.m_random_seed;
|
||||
m_phase_sticky = cfg.m_phase_sticky;
|
||||
m_dbg_flips = cfg.m_local_search_dbg_flips;
|
||||
}
|
||||
|
||||
public:
|
||||
local_search_config() {
|
||||
m_random_seed = 0;
|
||||
|
@ -54,12 +64,6 @@ namespace sat {
|
|||
void set_random_seed(unsigned s) { m_random_seed = s; }
|
||||
void set_best_known_value(unsigned v) { m_best_known_value = v; }
|
||||
|
||||
void set_config(config const& cfg) {
|
||||
m_mode = cfg.m_local_search_mode;
|
||||
m_random_seed = cfg.m_random_seed;
|
||||
m_phase_sticky = cfg.m_phase_sticky;
|
||||
m_dbg_flips = cfg.m_local_search_dbg_flips;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -74,12 +78,6 @@ namespace sat {
|
|||
typedef svector<bool> bool_vector;
|
||||
typedef svector<pbcoeff> coeff_vector;
|
||||
|
||||
// data structure for a term in objective function
|
||||
struct ob_term {
|
||||
bool_var var_id; // variable id, begin with 1
|
||||
int coefficient; // non-zero integer
|
||||
ob_term(bool_var v, int c): var_id(v), coefficient(c) {}
|
||||
};
|
||||
|
||||
struct stats {
|
||||
unsigned m_num_flips;
|
||||
|
@ -93,12 +91,12 @@ namespace sat {
|
|||
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_unit; // is this a unit literal
|
||||
literal m_explain; // explanation for unit assignment
|
||||
bool m_conf_change; // whether its configure changes since its last flip
|
||||
bool m_in_goodvar_stack;
|
||||
int m_score;
|
||||
int m_slack_score;
|
||||
int m_time_stamp; // the flip time stamp
|
||||
int m_cscc; // how many times its constraint state configure changes since its last flip
|
||||
bool_var_vector m_neighbors; // neighborhood variables
|
||||
coeff_vector m_watch[2];
|
||||
literal_vector m_bin[2];
|
||||
|
@ -112,7 +110,6 @@ namespace sat {
|
|||
m_in_goodvar_stack(false),
|
||||
m_score(0),
|
||||
m_slack_score(0),
|
||||
m_cscc(0),
|
||||
m_flips(0),
|
||||
m_slow_break(1e-5)
|
||||
{}
|
||||
|
@ -132,19 +129,44 @@ namespace sat {
|
|||
literal const* end() const { return m_literals.end(); }
|
||||
};
|
||||
|
||||
stats m_stats;
|
||||
|
||||
local_search_config m_config;
|
||||
|
||||
// objective function: maximize
|
||||
svector<ob_term> ob_constraint; // the objective function *constraint*, sorted in descending order
|
||||
|
||||
// information about the variable
|
||||
int_vector coefficient_in_ob_constraint; // var! initialized to be 0
|
||||
stats m_stats;
|
||||
local_search_config m_config;
|
||||
|
||||
vector<var_info> m_vars; // variables
|
||||
svector<bool_var> m_units; // unit clauses
|
||||
vector<constraint> m_constraints; // all constraints
|
||||
literal_vector m_assumptions; // temporary assumptions
|
||||
literal_vector m_prop_queue; // propagation queue
|
||||
unsigned m_num_non_binary_clauses;
|
||||
bool m_is_pb;
|
||||
bool m_is_unsat;
|
||||
unsigned_vector m_unsat_stack; // store all the unsat constraints
|
||||
unsigned_vector m_index_in_unsat_stack; // which position is a constraint in the unsat_stack
|
||||
|
||||
// configuration changed decreasing variables (score>0 and conf_change==true)
|
||||
bool_var_vector m_goodvar_stack;
|
||||
bool m_initializing;
|
||||
|
||||
|
||||
// information about solution
|
||||
unsigned m_best_unsat;
|
||||
double m_best_unsat_rate;
|
||||
double m_last_best_unsat_rate;
|
||||
// for non-known instance, set as maximal
|
||||
int m_best_known_value = INT_MAX; // best known value for this instance
|
||||
|
||||
unsigned m_max_steps = (1 << 30);
|
||||
|
||||
// dynamic noise
|
||||
double m_noise = 9800; // normalized by 10000
|
||||
double m_noise_delta = 0.05;
|
||||
|
||||
reslimit m_limit;
|
||||
random_gen m_rand;
|
||||
parallel* m_par;
|
||||
model m_model;
|
||||
|
||||
vector<var_info> m_vars;
|
||||
svector<bool_var> m_units;
|
||||
|
||||
inline int score(bool_var v) const { return m_vars[v].m_score; }
|
||||
inline void inc_score(bool_var v) { m_vars[v].m_score++; }
|
||||
|
@ -157,21 +179,10 @@ namespace sat {
|
|||
inline bool already_in_goodvar_stack(bool_var v) const { return m_vars[v].m_in_goodvar_stack; }
|
||||
inline bool conf_change(bool_var v) const { return m_vars[v].m_conf_change; }
|
||||
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 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; }
|
||||
|
||||
inline void set_best_unsat();
|
||||
/* TBD: other scores */
|
||||
|
||||
vector<constraint> m_constraints;
|
||||
|
||||
literal_vector m_assumptions;
|
||||
literal_vector m_prop_queue;
|
||||
|
||||
unsigned m_num_non_binary_clauses;
|
||||
bool m_is_pb;
|
||||
|
||||
inline bool is_pos(literal t) const { return !t.sign(); }
|
||||
inline bool is_true(bool_var v) const { return cur_solution(v); }
|
||||
|
@ -182,101 +193,37 @@ namespace sat {
|
|||
|
||||
unsigned num_constraints() const { return m_constraints.size(); } // constraint index from 1 to num_constraint
|
||||
|
||||
|
||||
unsigned constraint_slack(unsigned ci) const { return m_constraints[ci].m_slack; }
|
||||
|
||||
// unsat constraint stack
|
||||
bool m_is_unsat;
|
||||
unsigned_vector m_unsat_stack; // store all the unsat constraints
|
||||
unsigned_vector m_index_in_unsat_stack; // which position is a constraint in the unsat_stack
|
||||
|
||||
// configuration changed decreasing variables (score>0 and conf_change==true)
|
||||
bool_var_vector m_goodvar_stack;
|
||||
|
||||
|
||||
// information about solution
|
||||
unsigned m_best_unsat;
|
||||
double m_best_unsat_rate;
|
||||
double m_last_best_unsat_rate;
|
||||
int m_objective_value; // the objective function value corresponds to the current solution
|
||||
bool_vector m_best_solution; // !var: the best solution so far
|
||||
int m_best_objective_value = -1; // the objective value corresponds to the best solution so far
|
||||
// for non-known instance, set as maximal
|
||||
int m_best_known_value = INT_MAX; // best known value for this instance
|
||||
|
||||
unsigned m_max_steps = (1 << 30);
|
||||
|
||||
// dynamic noise
|
||||
double m_noise = 9800; // normalized by 10000
|
||||
double m_noise_delta = 0.05;
|
||||
|
||||
reslimit m_limit;
|
||||
random_gen m_rand;
|
||||
parallel* m_par;
|
||||
model m_model;
|
||||
|
||||
void init();
|
||||
void reinit();
|
||||
void reinit_orig();
|
||||
void init_cur_solution();
|
||||
void init_slack();
|
||||
void init_scores();
|
||||
void init_goodvars();
|
||||
|
||||
bool_var pick_var_gsat();
|
||||
|
||||
void flip_gsat(bool_var v);
|
||||
|
||||
void init_goodvars();
|
||||
void pick_flip_walksat();
|
||||
|
||||
void flip_walksat(bool_var v);
|
||||
|
||||
bool propagate(literal lit);
|
||||
|
||||
void add_propagation(literal lit);
|
||||
|
||||
void walksat();
|
||||
|
||||
void gsat();
|
||||
|
||||
void unsat(unsigned c);
|
||||
|
||||
void sat(unsigned c);
|
||||
|
||||
bool tie_breaker_sat(bool_var v1, bool_var v2);
|
||||
|
||||
bool tie_breaker_ccd(bool_var v1, bool_var v2);
|
||||
|
||||
void set_parameters();
|
||||
|
||||
void calculate_and_update_ob();
|
||||
|
||||
bool all_objectives_are_met() const;
|
||||
|
||||
void verify_solution() const;
|
||||
|
||||
void verify_unsat_stack() const;
|
||||
|
||||
void verify_constraint(constraint const& c) const;
|
||||
|
||||
void verify_slack(constraint const& c) const;
|
||||
void verify_slack() const;
|
||||
bool verify_goodvar() const;
|
||||
unsigned constraint_value(constraint const& c) const;
|
||||
|
||||
unsigned constraint_coeff(constraint const& c, literal l) const;
|
||||
|
||||
void print_info(std::ostream& out);
|
||||
|
||||
void extract_model();
|
||||
|
||||
bool check_goodvar();
|
||||
|
||||
void add_clause(unsigned sz, literal const* c);
|
||||
|
||||
void add_unit(literal lit);
|
||||
|
||||
void add_unit(literal lit, literal explain);
|
||||
std::ostream& display(std::ostream& out) const;
|
||||
|
||||
std::ostream& display(std::ostream& out, constraint const& c) const;
|
||||
|
||||
std::ostream& display(std::ostream& out, unsigned v, var_info const& vi) const;
|
||||
|
||||
public:
|
||||
|
@ -287,8 +234,6 @@ namespace sat {
|
|||
|
||||
~local_search();
|
||||
|
||||
void add_soft(bool_var v, int weight);
|
||||
|
||||
void add_cardinality(unsigned sz, literal const* c, unsigned k);
|
||||
|
||||
void add_pb(unsigned sz, literal const* c, unsigned const* coeffs, unsigned k);
|
||||
|
@ -307,8 +252,14 @@ namespace sat {
|
|||
|
||||
void set_phase(bool_var v, lbool f);
|
||||
|
||||
void set_bias(bool_var v, lbool f);
|
||||
|
||||
bool get_phase(bool_var v) const { return is_true(v); }
|
||||
|
||||
inline bool cur_solution(bool_var v) const { return m_vars[v].m_value; }
|
||||
|
||||
double break_count(bool_var v) const { return m_vars[v].m_slow_break; }
|
||||
|
||||
model& get_model() { return m_model; }
|
||||
|
||||
void collect_statistics(statistics& st) const;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue