257 lines
5.5 KiB
C
257 lines
5.5 KiB
C
#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
|