增量式计算打分
This commit is contained in:
parent
6861108609
commit
a95caaaaec
30
circuit.cpp
30
circuit.cpp
@ -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;
|
||||
}
|
@ -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);
|
||||
};
|
3
gate.cpp
3
gate.cpp
@ -55,6 +55,9 @@ int Gate::cal_value() {
|
||||
}
|
||||
res = !res;
|
||||
break;
|
||||
case INPUT:
|
||||
res = value;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
|
76
ls.cpp
76
ls.cpp
@ -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;
|
||||
|
2
main.cpp
2
main.cpp
@ -41,7 +41,5 @@ int main(int args, char* argv[]) {
|
||||
printf("checking valid circuit ...");
|
||||
printf(" result: %d.\n", circuit->is_valid_circuit());
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user