修改BMS
This commit is contained in:
parent
73a06ebe64
commit
1c7fed5672
@ -78,7 +78,7 @@ int* flip_need_update;
|
||||
std::vector<Gate*> flip_update_queue;
|
||||
|
||||
// incremental stem struct
|
||||
const int STEM_INC = 10000;
|
||||
const int STEM_INC = 20;
|
||||
const int STEM_WEIGHT_MAX = 1e9;
|
||||
ll stem_total_weight;
|
||||
int stem_total_cnt;
|
||||
@ -93,7 +93,6 @@ int** fault_weight;
|
||||
int** fault_detected;
|
||||
|
||||
void ls_init_circuit();
|
||||
void ls_init_stem(Gate* stem);
|
||||
void ls_init_weight(const std::unordered_set<Fault*> &faults);
|
||||
void ls_update_weight();
|
||||
void ls_init_data_structs();
|
||||
|
177
ls.cpp
177
ls.cpp
@ -18,8 +18,6 @@ bool Circuit::local_search(std::unordered_set<Fault*> &faults) {
|
||||
|
||||
// 随机生成初始电路
|
||||
ls_init_circuit();
|
||||
|
||||
assert(is_valid_circuit());
|
||||
|
||||
printf("local search!\n");
|
||||
|
||||
@ -40,7 +38,7 @@ bool Circuit::local_search(std::unordered_set<Fault*> &faults) {
|
||||
std::swap(stems_random[i], stems_random[rand()%stems_random.size()]);
|
||||
}
|
||||
|
||||
const int T = 50;
|
||||
const int T = 100;
|
||||
int t = 0;
|
||||
|
||||
for(int i=0; i<stems_random.size(); i++) {
|
||||
@ -51,7 +49,7 @@ bool Circuit::local_search(std::unordered_set<Fault*> &faults) {
|
||||
stem = t_stem;
|
||||
}
|
||||
if(t_score > 0) t++;
|
||||
if(t >= T) break;
|
||||
if(i >= T) break;
|
||||
}
|
||||
|
||||
if(max_score > 0) {
|
||||
@ -79,7 +77,7 @@ bool Circuit::local_search(std::unordered_set<Fault*> &faults) {
|
||||
flip_need_update[g->id] = false;
|
||||
flip_total_weight -= flip_weight[g->id];
|
||||
flip_total_cnt -= 1;
|
||||
ls_init_stem(g);
|
||||
ls_update(g);
|
||||
}
|
||||
|
||||
if(stem_total_cnt == stems.size() && flip_total_cnt == 0) {
|
||||
@ -247,169 +245,6 @@ ll Circuit::ls_score() {
|
||||
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];
|
||||
flip_total_cnt -= 1;
|
||||
}
|
||||
|
||||
if(stem->cal_value() == stem->value && !stem_satisfied[stem->id]){
|
||||
stem_satisfied[stem->id] = true;
|
||||
stem_total_weight -= stem_weight[stem->id];
|
||||
stem_total_cnt += 1;
|
||||
}
|
||||
|
||||
if(stem->cal_value() != stem->value && stem_satisfied[stem->id]) {
|
||||
stem_satisfied[stem->id] = false;
|
||||
stem_total_weight += stem_weight[stem->id];
|
||||
stem_total_cnt -= 1;
|
||||
}
|
||||
|
||||
//printf("flip: %s\n", stem->name.c_str());
|
||||
|
||||
//stem->value = !stem->value;
|
||||
|
||||
if(stem->isPO) {
|
||||
|
||||
if(stem->sa[!stem->value] == false) {
|
||||
fault_total_weight += fault_weight[stem->id][!stem->value];
|
||||
fault_total_cnt += 1;
|
||||
stem->sa[!stem->value] = true;
|
||||
}
|
||||
|
||||
if(stem->sa[stem->value] == true) {
|
||||
fault_total_weight -= fault_weight[stem->id][stem->value];
|
||||
fault_total_cnt -= 1;
|
||||
stem->sa[stem->value] = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::queue<Gate*> q;
|
||||
std::unordered_map<Gate*, int> used;
|
||||
std::vector<Gate*> suc_stems;
|
||||
|
||||
//printf("suc: %d %d\n", suc_stems.size(), stem->suc_stems.size());
|
||||
|
||||
q.push(stem);
|
||||
|
||||
while(!q.empty()) {
|
||||
Gate* g = q.front();
|
||||
q.pop();
|
||||
used[g] = false;
|
||||
for(Gate* out : g->outputs) {
|
||||
if(out->stem) {
|
||||
suc_stems.push_back(out);
|
||||
continue;
|
||||
}
|
||||
out->value = out->cal_value();
|
||||
if(!used[out]) {
|
||||
used[out] = true;
|
||||
q.push(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort(suc_stems.begin(), suc_stems.end(), cmp);
|
||||
// sort(stem->suc_stems.begin(), stem->suc_stems.end(), cmp);
|
||||
// assert(suc_stems == stem->suc_stems);
|
||||
|
||||
assert(q.empty());
|
||||
used.clear();
|
||||
|
||||
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];
|
||||
stem_total_cnt += 1;
|
||||
}
|
||||
|
||||
if(stem->cal_value() != stem->value && stem_satisfied[stem->id]) {
|
||||
stem_satisfied[stem->id] = false;
|
||||
stem_total_weight += stem_weight[stem->id];
|
||||
stem_total_cnt -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
while(!q.empty()) {
|
||||
Gate *g = q.front();
|
||||
q.pop();
|
||||
|
||||
used[g] = false;
|
||||
|
||||
bool right_value = (g->cal_value() == g->value);
|
||||
for(Gate* in : g->inputs) {
|
||||
in->value = !in->value;
|
||||
bool input_detected = (g->cal_value() != g->value);
|
||||
in->value = !in->value;
|
||||
|
||||
bool sa0 = right_value && input_detected && g->sa[!g->value] && in->value;
|
||||
bool sa1 = right_value && input_detected && g->sa[!g->value] && !in->value;
|
||||
|
||||
//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(), sa0, sa1);
|
||||
|
||||
in->sa_by_out[g] = std::make_pair(sa0, sa1);
|
||||
|
||||
bool old_sa[2];
|
||||
old_sa[0] = in->sa[0];
|
||||
old_sa[1] = in->sa[1];
|
||||
|
||||
in->sa[0] = in->sa[1] = 0;
|
||||
for(Gate* out : in->outputs) {
|
||||
auto &p = in->sa_by_out[out];
|
||||
//printf("%d %d\n", p.first, p.second);
|
||||
in->sa[0] |= p.first;
|
||||
in->sa[1] |= p.second;
|
||||
}
|
||||
|
||||
if(in->stem && !in->isPI && (in->sa[0] != old_sa[0] || in->sa[1] != old_sa[1])) {
|
||||
|
||||
for(Gate* pre : in->pre_stems) {
|
||||
if(flip_need_update[pre->id]) continue;
|
||||
|
||||
flip_need_update[pre->id] = true;
|
||||
flip_update_queue.push_back(pre);
|
||||
|
||||
flip_total_weight += flip_weight[pre->id];
|
||||
flip_total_cnt += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(old_sa[0] != in->sa[0]) {
|
||||
if(in->sa[0]) {
|
||||
fault_total_weight += fault_weight[in->id][0];
|
||||
fault_total_cnt += 1;
|
||||
} else {
|
||||
fault_total_weight -= fault_weight[in->id][0];
|
||||
fault_total_cnt -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(old_sa[1] != in->sa[1]) {
|
||||
if(in->sa[1]) {
|
||||
fault_total_weight += fault_weight[in->id][1];
|
||||
fault_total_cnt += 1;
|
||||
} else {
|
||||
fault_total_weight -= fault_weight[in->id][1];
|
||||
fault_total_cnt -= 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]) {
|
||||
used[in] = true;
|
||||
q.push(in);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Circuit::ls_init_weight(const std::unordered_set<Fault*> &faults) {
|
||||
for(Gate* s : stems) {
|
||||
stem_weight[s->id] = 1;
|
||||
@ -435,7 +270,7 @@ void Circuit::ls_init_circuit() {
|
||||
}
|
||||
|
||||
for(int i=stems.size()-1; i>=0; i--) {
|
||||
ls_init_stem(stems[i]);
|
||||
ls_update(stems[i]);
|
||||
}
|
||||
|
||||
while(!flip_update_queue.empty()) {
|
||||
@ -445,7 +280,7 @@ void Circuit::ls_init_circuit() {
|
||||
flip_need_update[g->id] = false;
|
||||
flip_total_weight -= flip_weight[g->id];
|
||||
flip_total_cnt -= 1;
|
||||
ls_init_stem(g);
|
||||
ls_update(g);
|
||||
}
|
||||
}
|
||||
|
||||
@ -496,7 +331,7 @@ void Circuit::ls_init_data_structs() {
|
||||
}
|
||||
|
||||
|
||||
void Circuit::ls_init_stem(Gate* stem) {
|
||||
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];
|
||||
|
6
main.cpp
6
main.cpp
@ -38,11 +38,11 @@ int main(int args, char* argv[]) {
|
||||
|
||||
while(true) {
|
||||
bool ls = circuit->local_search(faults);
|
||||
bool is_valid = circuit->is_valid_circuit();
|
||||
//bool is_valid = circuit->is_valid_circuit();
|
||||
printf("checking valid circuit ...");
|
||||
printf(" result: %d.\n", is_valid);
|
||||
//printf(" result: %d.\n", is_valid);
|
||||
if(!ls) break;
|
||||
if(!is_valid) break;
|
||||
//if(!is_valid) break;
|
||||
if(faults.size() == 0) break;
|
||||
}
|
||||
|
||||
|
34888
output.txt
34888
output.txt
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user