3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-20 21:03:39 +00:00

latest updates from Cliff

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-02-27 16:37:31 -08:00
parent 88e7c240b7
commit c22359820d
3 changed files with 177 additions and 163 deletions

View file

@ -37,10 +37,11 @@ namespace sat {
var_neighbor.push_back(bool_var_vector()); var_neighbor.push_back(bool_var_vector());
for (bool_var v = 1; v <= num_vars(); ++v) { for (bool_var v = 1; v <= num_vars(); ++v) {
//std::cout << pos_var_term[v].size() << '\t' << neg_var_term[v].size() << '\n';
bool_vector is_neighbor(num_vars() + 1, false); bool_vector is_neighbor(num_vars() + 1, false);
var_neighbor.push_back(bool_var_vector()); var_neighbor.push_back(bool_var_vector());
for (unsigned i = 0; i < var_term[v].size(); ++i) { for (unsigned i = 0; i < pos_var_term[v].size(); ++i) {
unsigned c = var_term[v][i].constraint_id; unsigned c = pos_var_term[v][i];
for (unsigned j = 0; j < constraint_term[c].size(); ++j) { for (unsigned j = 0; j < constraint_term[c].size(); ++j) {
bool_var w = constraint_term[c][j].var_id; bool_var w = constraint_term[c][j].var_id;
if (w == v || is_neighbor[w]) continue; if (w == v || is_neighbor[w]) continue;
@ -48,6 +49,15 @@ namespace sat {
var_neighbor.back().push_back(w); var_neighbor.back().push_back(w);
} }
} }
for (unsigned i = 0; i < neg_var_term[v].size(); ++i) {
unsigned c = neg_var_term[v][i];
for (unsigned j = 0; j < constraint_term[c].size(); ++j) {
bool_var w = constraint_term[c][j].var_id;
if (w == v || is_neighbor[w]) continue;
is_neighbor[w] = true;
var_neighbor.back().push_back(w);
}
}
} }
for (unsigned i = 0; i < ob_constraint.size(); ++i) for (unsigned i = 0; i < ob_constraint.size(); ++i)
coefficient_in_ob_constraint[ob_constraint[i].var_id] = ob_constraint[i].coefficient; coefficient_in_ob_constraint[ob_constraint[i].var_id] = ob_constraint[i].coefficient;
@ -84,25 +94,32 @@ namespace sat {
// figure out variables scores and sscores // figure out variables scores and sscores
void local_search::init_scores() { void local_search::init_scores() {
for (unsigned v = 1; v <= num_vars(); ++v) { for (unsigned v = 1; v <= num_vars(); ++v) {
for (unsigned i = 0; i < var_term[v].size(); ++i) { int_vector truep, falsep;
int c = var_term[v][i].constraint_id; if (cur_solution[v]) {
if (cur_solution[v] != var_term[v][i].sense) { truep = pos_var_term[v];
// will ++true_terms_count[c] falsep = neg_var_term[v];
// will --slack }
if (constraint_slack[c] <= 0) { else {
--sscore[v]; truep = neg_var_term[v];
if (constraint_slack[c] == 0) falsep = pos_var_term[v];
--m_var_info[v].m_score; }
} for (unsigned i = 0; i < falsep.size(); ++i) {
} int c = falsep[i];
else { // if (cur_solution[v] == var_term[v][i].sense) // will --slack
// will --true_terms_count[c] if (constraint_slack[c] <= 0) {
// will ++slack --sscore[v];
if (constraint_slack[c] <= -1) { if (constraint_slack[c] == 0)
++sscore[v]; --m_var_info[v].m_score;
if (constraint_slack[c] == -1) }
++m_var_info[v].m_score; }
} for (unsigned i = 0; i < truep.size(); ++i) {
int c = truep[i];
// will --true_terms_count[c]
// will ++slack
if (constraint_slack[c] <= -1) {
++sscore[v];
if (constraint_slack[c] == -1)
++m_var_info[v].m_score;
} }
} }
} }
@ -186,10 +203,13 @@ namespace sat {
m_num_vars = std::max(c[i].var() + 1, m_num_vars); m_num_vars = std::max(c[i].var() + 1, m_num_vars);
// var_term.reserve(c[i].var() + 1); // var_term.reserve(c[i].var() + 1);
term t; term t;
t.constraint_id = id;
t.var_id = c[i].var(); t.var_id = c[i].var();
t.sense = c[i].sign(); t.sense = c[i].sign();
var_term[t.var_id].push_back(t); if (t.sense)
pos_var_term[t.var_id].push_back(id);
else
neg_var_term[t.var_id].push_back(id);
//var_term[t.var_id].push_back(t);
constraint_term[id].push_back(t); constraint_term[id].push_back(t);
} }
constraint_k.push_back(k); constraint_k.push_back(k);
@ -305,20 +325,21 @@ namespace sat {
reach_known_best_value = true; reach_known_best_value = true;
break; break;
} }
} }
flipvar = pick_var(); flipvar = pick_var();
flip(flipvar); flip(flipvar);
time_stamp[flipvar] = step; time_stamp[flipvar] = step;
} }
// take a look at watch if (tries % 10 == 0) {
stop = clock(); // take a look at watch
elapsed_time = (double)(stop - start) / CLOCKS_PER_SEC; stop = clock();
if (tries % 10 == 0) elapsed_time = (double)(stop - start) / CLOCKS_PER_SEC;
std::cout << tries << ": " << elapsed_time << '\n'; std::cout << tries << ": " << elapsed_time << '\n';
}
if (elapsed_time > cutoff_time) if (elapsed_time > cutoff_time)
reach_cutoff_time = true; reach_cutoff_time = true;
//if (reach_known_best_value || reach_cutoff_time) if (reach_known_best_value || reach_cutoff_time)
// break; break;
} }
if (reach_known_best_value) { if (reach_known_best_value) {
std::cout << elapsed_time << "\n"; std::cout << elapsed_time << "\n";
@ -334,8 +355,6 @@ namespace sat {
void local_search::flip(bool_var flipvar) void local_search::flip(bool_var flipvar)
{ {
static unsigned_vector hack_vector;
hack_vector.reset();
// already changed truth value!!!! // already changed truth value!!!!
cur_solution[flipvar] = !cur_solution[flipvar]; cur_solution[flipvar] = !cur_solution[flipvar];
@ -343,95 +362,99 @@ namespace sat {
int org_flipvar_score = score(flipvar); int org_flipvar_score = score(flipvar);
int org_flipvar_sscore = sscore[flipvar]; int org_flipvar_sscore = sscore[flipvar];
int_vector truep, falsep;
if (cur_solution[flipvar]) {
truep = pos_var_term[flipvar];
falsep = neg_var_term[flipvar];
}
else {
truep = neg_var_term[flipvar];
falsep = pos_var_term[flipvar];
}
// update related clauses and neighbor vars // update related clauses and neighbor vars
svector<term> const& constraints = var_term[flipvar]; for (unsigned i = 0; i < truep.size(); ++i) {
unsigned num_cs = constraints.size(); c = truep[i];
for (unsigned i = 0; i < num_cs; ++i) { //++true_terms_count[c];
c = constraints[i].constraint_id; --constraint_slack[c];
if (cur_solution[flipvar] == constraints[i].sense) { switch (constraint_slack[c]) {
//++true_terms_count[c]; case -2: // from -1 to -2
--constraint_slack[c]; for (unsigned j = 0; j < constraint_term[c].size(); ++j) {
switch (constraint_slack[c]) { v = constraint_term[c][j].var_id;
case -2: // from -1 to -2 // flipping the slack increasing var will no long sat this constraint
for (unsigned j = 0; j < constraint_term[c].size(); ++j) { if (cur_solution[v] == constraint_term[c][j].sense)
v = constraint_term[c][j].var_id; //score[v] -= constraint_weight[c];
// flipping the slack increasing var will no long sat this constraint --m_var_info[v].m_score;
if (cur_solution[v] == constraint_term[c][j].sense) }
//score[v] -= constraint_weight[c]; break;
--m_var_info[v].m_score; case -1: // from 0 to -1: sat -> unsat
} for (unsigned j = 0; j < constraint_term[c].size(); ++j) {
break; v = constraint_term[c][j].var_id;
case -1: // from 0 to -1: sat -> unsat ++cscc[v];
for (unsigned j = 0; j < constraint_term[c].size(); ++j) { //score[v] += constraint_weight[c];
v = constraint_term[c][j].var_id; ++m_var_info[v].m_score;
++cscc[v]; // slack increasing var
//score[v] += constraint_weight[c]; if (cur_solution[v] == constraint_term[c][j].sense)
++m_var_info[v].m_score; ++sscore[v];
hack_vector.push_back(v); }
// slack increasing var unsat(c);
if (cur_solution[v] == constraint_term[c][j].sense) break;
++sscore[v]; case 0: // from 1 to 0
} for (unsigned j = 0; j < constraint_term[c].size(); ++j) {
unsat(c); v = constraint_term[c][j].var_id;
break; // flip the slack decreasing var will falsify this constraint
case 0: // from 1 to 0 if (cur_solution[v] != constraint_term[c][j].sense) {
for (unsigned j = 0; j < constraint_term[c].size(); ++j) { //score[v] -= constraint_weight[c];
v = constraint_term[c][j].var_id; --m_var_info[v].m_score;
// flip the slack decreasing var will falsify this constraint --sscore[v];
if (cur_solution[v] != constraint_term[c][j].sense) { }
//score[v] -= constraint_weight[c]; }
--m_var_info[v].m_score; break;
--sscore[v]; default:
} break;
} }
break; }
default: for (unsigned i = 0; i < falsep.size(); ++i) {
break; c = falsep[i];
} //--true_terms_count[c];
} ++constraint_slack[c];
else { // if (cur_solution[flipvar] != var_term[i].sense) switch (constraint_slack[c]) {
//--true_terms_count[c]; case 1: // from 0 to 1
++constraint_slack[c]; for (unsigned j = 0; j < constraint_term[c].size(); ++j) {
switch (constraint_slack[c]) { v = constraint_term[c][j].var_id;
case 1: // from 0 to 1 // flip the slack decreasing var will no long falsify this constraint
for (unsigned j = 0; j < constraint_term[c].size(); ++j) { if (cur_solution[v] != constraint_term[c][j].sense) {
v = constraint_term[c][j].var_id; //score[v] += constraint_weight[c];
// flip the slack decreasing var will no long falsify this constraint ++m_var_info[v].m_score;
if (cur_solution[v] != constraint_term[c][j].sense) { ++sscore[v];
//score[v] += constraint_weight[c]; }
++m_var_info[v].m_score; }
hack_vector.push_back(v); break;
++sscore[v]; case 0: // from -1 to 0: unsat -> sat
} for (unsigned j = 0; j < constraint_term[c].size(); ++j) {
} v = constraint_term[c][j].var_id;
break; ++cscc[v];
case 0: // from -1 to 0: unsat -> sat //score[v] -= constraint_weight[c];
for (unsigned j = 0; j < constraint_term[c].size(); ++j) { --m_var_info[v].m_score;
v = constraint_term[c][j].var_id; // slack increasing var no longer sat this var
++cscc[v]; if (cur_solution[v] == constraint_term[c][j].sense)
//score[v] -= constraint_weight[c]; --sscore[v];
--m_var_info[v].m_score; }
// slack increasing var no longer sat this var sat(c);
if (cur_solution[v] == constraint_term[c][j].sense) break;
--sscore[v]; case -1: // from -2 to -1
} for (unsigned j = 0; j < constraint_term[c].size(); ++j) {
sat(c); v = constraint_term[c][j].var_id;
break; // flip the slack increasing var will satisfy this constraint
case -1: // from -2 to -1 if (cur_solution[v] == constraint_term[c][j].sense) {
for (unsigned j = 0; j < constraint_term[c].size(); ++j) { //score[v] += constraint_weight[c];
v = constraint_term[c][j].var_id; ++m_var_info[v].m_score;
// flip the slack increasing var will satisfy this constraint }
if (cur_solution[v] == constraint_term[c][j].sense) { }
//score[v] += constraint_weight[c]; break;
++m_var_info[v].m_score; default:
hack_vector.push_back(v); break;
} }
}
break;
default:
break;
}
}
} }
m_var_info[flipvar].m_score = -org_flipvar_score; m_var_info[flipvar].m_score = -org_flipvar_score;
@ -453,7 +476,6 @@ namespace sat {
} }
// update all flipvar's neighbor's conf_change to true, add goodvar/okvar // update all flipvar's neighbor's conf_change to true, add goodvar/okvar
#if 0
unsigned sz = var_neighbor[flipvar].size(); unsigned sz = var_neighbor[flipvar].size();
for (unsigned i = 0; i < sz; ++i) { for (unsigned i = 0; i < sz; ++i) {
v = var_neighbor[flipvar][i]; v = var_neighbor[flipvar][i];
@ -463,18 +485,7 @@ namespace sat {
m_var_info[v].m_in_goodvar_stack = true; m_var_info[v].m_in_goodvar_stack = true;
} }
} }
#else
unsigned sz = hack_vector.size();
for (unsigned i = 0; i < sz; ++i)
{
v = hack_vector[i];
m_var_info[v].m_conf_change = true;
if (score(v) > 0 && !already_in_goodvar_stack(v)) {
goodvar_stack.push_back(v);
m_var_info[v].m_in_goodvar_stack = true;
}
}
#endif
} }
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) {
@ -574,7 +585,7 @@ namespace sat {
} }
void local_search::print_info() { void local_search::print_info() {
for (int v = 1; v <= num_vars(); ++v) { for (unsigned v = 1; v <= num_vars(); ++v) {
std::cout << var_neighbor[v].size() << '\t' << cur_solution[v] << '\t' << conf_change(v) << '\t' << score(v) << '\t' << sscore[v] << '\n'; std::cout << var_neighbor[v].size() << '\t' << cur_solution[v] << '\t' << conf_change(v) << '\t' << score(v) << '\t' << sscore[v] << '\n';
} }
} }

View file

@ -64,7 +64,7 @@ namespace sat {
// data structure for a term in constraint // data structure for a term in constraint
struct term { struct term {
int constraint_id; // constraint it belongs to //int constraint_id; // constraint it belongs to
int var_id; // variable id, begin with 1 int var_id; // variable id, begin with 1
bool sense; // 1 for positive, 0 for negative bool sense; // 1 for positive, 0 for negative
//int coefficient; // all constraints are cardinality: coefficient=1 //int coefficient; // all constraints are cardinality: coefficient=1
@ -76,8 +76,10 @@ namespace sat {
// terms arrays // terms arrays
svector<term> var_term[MAX_VARS]; // var_term[i][j] means the j'th term of var i //svector<term> var_term[MAX_VARS]; // var_term[i][j] means the j'th term of var i
svector<term> constraint_term[MAX_CONSTRAINTS]; // constraint_term[i][j] means the j'th term of constraint i int_vector pos_var_term[MAX_VARS];
int_vector neg_var_term[MAX_VARS];
svector<term> constraint_term[MAX_CONSTRAINTS]; // constraint_term[i][j] means the j'th term of constraint i
unsigned m_num_vars, m_num_constraints; unsigned m_num_vars, m_num_constraints;
// parameters of the instance // parameters of the instance
@ -136,7 +138,7 @@ namespace sat {
// cutoff // cutoff
int cutoff_time = 1; // seconds int cutoff_time = 1; // seconds
int max_steps = 2000000000; // < 2147483647 unsigned max_steps = 2000000000; // < 2147483647
clock_t start, stop; clock_t start, stop;
double best_time; double best_time;

View file

@ -80,31 +80,32 @@ void tst_sat_local_search(char ** argv, int argc, int& i) {
int v; int v;
while (i + 1 < argc) { while (i + 1 < argc) {
std::cout << argv[i + 1] << "\n";
// set other ad hoc parameters. // set other ad hoc parameters.
if (argv[i + 1][0] == '-' && i + 2 < argc) { if (argv[i + 1][0] == '-' && i + 2 < argc) {
switch (argv[i + 1][1]) { switch (argv[i + 1][1]) {
case 's': // seed case 's': // seed
v = atoi(argv[i + 2]); v = atoi(argv[i + 2]);
local_search.m_config.set_seed(v); local_search.m_config.set_seed(v);
break; break;
case 't': // cutoff_time case 't': // cutoff_time
v = atoi(argv[i + 2]); v = atoi(argv[i + 2]);
local_search.m_config.set_cutoff_time(v); local_search.m_config.set_cutoff_time(v);
break; break;
case 'i': // strategy_id case 'i': // strategy_id
v = atoi(argv[i + 2]); v = atoi(argv[i + 2]);
local_search.m_config.set_strategy_id(v); local_search.m_config.set_strategy_id(v);
break; break;
case 'b': // best_known_value case 'b': // best_known_value
v = atoi(argv[i + 2]); v = atoi(argv[i + 2]);
local_search.m_config.set_best_known_value(v); local_search.m_config.set_best_known_value(v);
break; break;
default: default:
++i; ++i;
v = -1; v = -1;
break; break;
} }
} }
++i; ++i;
} }