2023-02-14 16:58:22 +08:00

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