#ifndef _PMS_H_ #define _PMS_H_ #include "basis_pms.h" #include "deci.h" void Satlike::update_goodvarstack1(int flipvar) { int v; //remove the vars no longer goodvar in goodvar stack for (int index = goodvar_stack_fill_pointer - 1; index >= 0; index--) { v = goodvar_stack[index]; if (score[v] <= 0) { goodvar_stack[index] = mypop(goodvar_stack); already_in_goodvar_stack[v] = -1; } } //add goodvar for (int i = 0; i < var_neighbor_count[flipvar]; ++i) { v = var_neighbor[flipvar][i]; if (score[v] > 0) { if (already_in_goodvar_stack[v] == -1) { already_in_goodvar_stack[v] = goodvar_stack_fill_pointer; mypush(v, goodvar_stack); } } } } void Satlike::update_goodvarstack2(int flipvar) { if (score[flipvar] > 0 && already_in_goodvar_stack[flipvar] == -1) { already_in_goodvar_stack[flipvar] = goodvar_stack_fill_pointer; mypush(flipvar, goodvar_stack); } else if (score[flipvar] <= 0 && already_in_goodvar_stack[flipvar] != -1) { int index = already_in_goodvar_stack[flipvar]; int last_v = mypop(goodvar_stack); goodvar_stack[index] = last_v; already_in_goodvar_stack[last_v] = index; already_in_goodvar_stack[flipvar] = -1; } int i, v; for (i = 0; i < var_neighbor_count[flipvar]; ++i) { v = var_neighbor[flipvar][i]; if (score[v] > 0) { if (already_in_goodvar_stack[v] == -1) { already_in_goodvar_stack[v] = goodvar_stack_fill_pointer; mypush(v, goodvar_stack); } } else if (already_in_goodvar_stack[v] != -1) { int index = already_in_goodvar_stack[v]; int last_v = mypop(goodvar_stack); goodvar_stack[index] = last_v; already_in_goodvar_stack[last_v] = index; already_in_goodvar_stack[v] = -1; } } } void Satlike::flip(int flipvar) { int i, v, c; int index; lit *clause_c; int org_flipvar_score = score[flipvar]; cur_soln[flipvar] = 1 - cur_soln[flipvar]; for (i = 0; i < var_lit_count[flipvar]; ++i) { c = var_lit[flipvar][i].clause_num; clause_c = clause_lit[c]; if (cur_soln[flipvar] == var_lit[flipvar][i].sense) { ++sat_count[c]; if (sat_count[c] == 2) //sat_count from 1 to 2 { score[sat_var[c]] += clause_weight[c]; } else if (sat_count[c] == 1) // sat_count from 0 to 1 { sat_var[c] = flipvar; //record the only true lit's var for (lit *p = clause_c; (v = p->var_num) != 0; p++) { score[v] -= clause_weight[c]; } sat(c); } } else // cur_soln[flipvar] != cur_lit.sense { --sat_count[c]; if (sat_count[c] == 1) //sat_count from 2 to 1 { for (lit *p = clause_c; (v = p->var_num) != 0; p++) { if (p->sense == cur_soln[v]) { score[v] -= clause_weight[c]; sat_var[c] = v; break; } } } else if (sat_count[c] == 0) //sat_count from 1 to 0 { for (lit *p = clause_c; (v = p->var_num) != 0; p++) { score[v] += clause_weight[c]; } unsat(c); } //end else if } //end else } //update information of flipvar score[flipvar] = -org_flipvar_score; update_goodvarstack1(flipvar); } void Satlike::print_best_solution() { if (best_soln_feasible == 0) return; printf("v"); for (int i = 1; i <= num_vars; i++) { printf(" "); if (best_soln[i] == 0) printf("-"); printf("%d", i); } printf("\n"); } bool Satlike::verify_sol() { int c, j, flag; long long verify_unsat_weight = 0; for (c = 0; c < num_clauses; ++c) { flag = 0; for (j = 0; j < clause_lit_count[c]; ++j) if (best_soln[clause_lit[c][j].var_num] == clause_lit[c][j].sense) { flag = 1; break; } if (flag == 0) { if (org_clause_weight[c] == top_clause_weight) //verify hard clauses { //output the clause unsatisfied by the solution cout << "c Error: hard clause " << c << " is not satisfied" << endl; cout << "c "; for (j = 0; j < clause_lit_count[c]; ++j) { if (clause_lit[c][j].sense == 0) cout << "-"; cout << clause_lit[c][j].var_num << " "; } cout << endl; cout << "c "; for (j = 0; j < clause_lit_count[c]; ++j) cout << best_soln[clause_lit[c][j].var_num] << " "; cout << endl; return 0; } else { verify_unsat_weight += org_clause_weight[c]; } } } if (verify_unsat_weight == opt_unsat_weight) return 1; else { cout << "c Error: find opt=" << opt_unsat_weight << ", but verified opt=" << verify_unsat_weight << endl; } return 0; } void Satlike::simple_print() { if (best_soln_feasible != 0) { if (verify_sol() == 1) cout << opt_unsat_weight << '\t' << opt_time << endl; else cout << "solution is wrong " << endl; } else cout << -1 << '\t' << -1 << endl; } inline void Satlike::unsat(int clause) { if (org_clause_weight[clause] == top_clause_weight) { index_in_hardunsat_stack[clause] = hardunsat_stack_fill_pointer; mypush(clause, hardunsat_stack); hard_unsat_nb++; } else { index_in_softunsat_stack[clause] = softunsat_stack_fill_pointer; mypush(clause, softunsat_stack); soft_unsat_weight += org_clause_weight[clause]; } } inline void Satlike::sat(int clause) { int index, last_unsat_clause; if (org_clause_weight[clause] == top_clause_weight) { last_unsat_clause = mypop(hardunsat_stack); index = index_in_hardunsat_stack[clause]; hardunsat_stack[index] = last_unsat_clause; index_in_hardunsat_stack[last_unsat_clause] = index; hard_unsat_nb--; } else { last_unsat_clause = mypop(softunsat_stack); index = index_in_softunsat_stack[clause]; softunsat_stack[index] = last_unsat_clause; index_in_softunsat_stack[last_unsat_clause] = index; soft_unsat_weight -= org_clause_weight[clause]; } } #endif