增量式计算打分

This commit is contained in:
YuhangQ 2023-02-20 14:41:19 +08:00
parent 6861108609
commit a95caaaaec
7 changed files with 111 additions and 8 deletions

BIN
atpg

Binary file not shown.

View File

@ -77,8 +77,32 @@ void Circuit::print_gates() {
bool Circuit::is_valid_circuit() {
ll flip_total_weight = 0;
ll stem_total_weight = 0;
ll fault_total_weight = 0;
//printf("flip: %d, stem: %d, fault:%d\n", flip_total_weight, stem_total_weight, fault_total_weight);
for(Gate* g : gates) {
if(flip_need_update[g->id]) {
flip_total_weight += flip_weight[g->id];
}
if(g->stem) {
stem_total_weight += (g->cal_value() == g->value);
}
if(g->sa[0]) {
fault_total_weight += fault_weight[g->id][0];
}
if(g->sa[1]) {
fault_total_weight += fault_weight[g->id][1];
}
// 检查门的赋值情况
if(!g->stem && g->cal_value() != g->value) {
return false;
@ -118,5 +142,11 @@ bool Circuit::is_valid_circuit() {
}
if(this->flip_total_weight != flip_total_weight || this->stem_total_weight != stem_total_weight || this->fault_total_weight != fault_total_weight) {
printf("CIRCUIT CHECK FAILED!\n");
printf("[wrong] flip: %d, stem: %d, fault:%d\n", this->flip_total_weight, this->stem_total_weight, this->fault_total_weight);
printf("[right] flip: %d, stem: %d, fault:%d\n", flip_total_weight, stem_total_weight, fault_total_weight);
}
return true;
}

View File

@ -80,6 +80,10 @@ int** fault_detected;
void ls_init_circuit();
void ls_init_weight(const std::vector<Fault*> &faults);
void ls_init_data_structs();
void ls_flip(Gate* stem);
void ls_block_recal(Gate* stem);
void ls_flip(Gate* stem);
void ls_update(Gate* stem);
int ls_score(Gate* stem);
};

View File

@ -55,6 +55,9 @@ int Gate::cal_value() {
}
res = !res;
break;
case INPUT:
res = value;
break;
default:
assert(false);
break;

76
ls.cpp
View File

@ -29,20 +29,57 @@ bool cmp(Gate* a, Gate *b) {
return a->id > b->id;
}
void Circuit::ls_flip(Gate* stem) {
stem->value = !stem->value;
ls_block_recal(stem);
}
void Circuit::ls_update(Gate* stem) {
ls_block_recal(stem);
}
int Circuit::ls_score(Gate* stem) {
ls_flip(stem);
int score = -flip_total_weight + stem_total_weight + fault_total_weight;
ls_flip(stem);
return score;
}
void Circuit::ls_block_recal(Gate* stem) {
if(flip_need_update[stem->id]) {
flip_need_update[stem->id] = false;
flip_total_weight -= flip_weight[stem->id];
}
if(stem->cal_value() == stem->value && !stem_satisfied[stem->id]){
stem_satisfied[stem->id] = true;
stem_total_weight += stem_weight[stem->id];
}
if(stem->cal_value() != stem->value && stem_satisfied[stem->id]) {
stem_satisfied[stem->id] = false;
stem_total_weight -= stem_weight[stem->id];
}
//printf("flip: %s\n", stem->name.c_str());
//stem->value = !stem->value;
if(stem->isPO) {
stem->sa[!stem->value] = true;
stem->sa[stem->value] = false;
if(stem->sa[!stem->value] == false) {
fault_total_weight += fault_weight[stem->id][!stem->value];
stem->sa[!stem->value] = true;
}
if(stem->sa[stem->value] == true) {
fault_total_weight -= fault_weight[stem->id][stem->value];
stem->sa[stem->value] = false;
}
}
std::queue<Gate*> q;
@ -73,6 +110,16 @@ void Circuit::ls_flip(Gate* stem) {
for(Gate* stem : suc_stems) {
q.push(stem);
if(stem->cal_value() == stem->value && !stem_satisfied[stem->id]){
stem_satisfied[stem->id] = true;
stem_total_weight += stem_weight[stem->id];
}
if(stem->cal_value() != stem->value && stem_satisfied[stem->id]) {
stem_satisfied[stem->id] = false;
stem_total_weight -= stem_weight[stem->id];
}
}
while(!q.empty()) {
@ -124,6 +171,22 @@ void Circuit::ls_flip(Gate* stem) {
}
}
if(old_sa[0] != in->sa[0]) {
if(in->sa[0]) {
fault_total_weight += fault_weight[in->id][0];
} else {
fault_total_weight -= fault_weight[in->id][0];
}
}
if(old_sa[1] != in->sa[1]) {
if(in->sa[1]) {
fault_total_weight += fault_weight[in->id][1];
} else {
fault_total_weight -= fault_weight[in->id][1];
}
}
//printf("gate: %s -> %s rv: %d id: %d p:%d sa0: %d sa1: %d\n", in->name.c_str(), g->name.c_str(), right_value, input_detected, g->is_propagated(), in->sa[0], in->sa[1]);
if(!in->stem && !used[in]) {
@ -156,14 +219,16 @@ void Circuit::ls_init_circuit() {
}
for(int i=stems.size()-1; i>=0; i--) {
ls_flip(stems[i]);
ls_update(stems[i]);
}
while(!flip_update_queue.empty()) {
Gate* g = flip_update_queue.back();
flip_update_queue.pop_back();
if(!flip_need_update[g->id]) continue;
flip_need_update[g->id] = false;
ls_flip(g);
flip_total_weight -= flip_weight[g->id];
ls_update(g);
}
}
@ -187,6 +252,9 @@ void Circuit::ls_init_data_structs() {
}
} else {
flip_total_weight = 0;
stem_total_weight = 0;
fault_total_weight = 0;
for(int i=0; i<MAX_LEN; i++) {
flip_weight[i] = 0;
flip_need_update[i] = 0;

View File

@ -41,7 +41,5 @@ int main(int args, char* argv[]) {
printf("checking valid circuit ...");
printf(" result: %d.\n", circuit->is_valid_circuit());
return 0;
}

View File

@ -7,7 +7,7 @@
#编译工具用g++以同时支持C和C++程序,以及二者的混合编译
CC=g++
CPPFLAGS=-O3 -std=c++17
CPPFLAGS=-O3 -std=c++17 -g
#使用$(winldcard *.c)来获取工作目录下的所有.c文件的列表
#sources:=main.cpp command.c