最初版本完工
This commit is contained in:
parent
94224308de
commit
acfeb1be4b
8829
_c6288.txt
Normal file
8829
_c6288.txt
Normal file
File diff suppressed because it is too large
Load Diff
2484
c6288.bench
Normal file
2484
c6288.bench
Normal file
File diff suppressed because it is too large
Load Diff
28
circuit.cpp
28
circuit.cpp
@ -7,9 +7,12 @@
|
||||
|
||||
void Circuit::init_stems() {
|
||||
for(auto& gate: gates) {
|
||||
if(gate->outputs.size() >= 2) {
|
||||
if(rand() % 10 <= 2) {
|
||||
gate->stem = true;
|
||||
}
|
||||
// if(gate->outputs.size() >= 3) {
|
||||
|
||||
// }
|
||||
if(gate->stem) {
|
||||
stems.push_back(gate);
|
||||
}
|
||||
@ -116,29 +119,35 @@ bool Circuit::is_valid_circuit() {
|
||||
flip_total_cnt++;
|
||||
}
|
||||
|
||||
if(g->stem && g->cal_value() == g->value) {
|
||||
if(g->stem && g->cal_value() != g->value) {
|
||||
stem_total_weight += stem_weight[g->id];
|
||||
}
|
||||
|
||||
if(g->stem && g->cal_value() == g->value) {
|
||||
stem_total_cnt++;
|
||||
}
|
||||
|
||||
if(g->sa[0]) {
|
||||
fault_total_weight += fault_weight[g->id][0];
|
||||
fault_total_cnt++;
|
||||
fault_total_cnt += 1;
|
||||
}
|
||||
|
||||
if(g->sa[1]) {
|
||||
fault_total_weight += fault_weight[g->id][1];
|
||||
fault_total_cnt++;
|
||||
fault_total_cnt += 1;
|
||||
}
|
||||
|
||||
// 检查门的赋值情况
|
||||
if(!g->stem && g->cal_value() != g->value) {
|
||||
if(g->cal_value() != g->value) {
|
||||
printf("WRONG-ASSGIN: %s \n", g->name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查 PO 的传播设定是否正确
|
||||
if(g->isPO) {
|
||||
if(g->sa[g->value] != 0 || g->sa[!g->value] == 0 ) return false;
|
||||
if(g->sa[g->value] != 0 || g->sa[!g->value] == 0 ) {
|
||||
printf("WRONG-PO: %s \n", g->name.c_str());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -164,22 +173,23 @@ bool Circuit::is_valid_circuit() {
|
||||
}
|
||||
|
||||
if(sa0 != g->sa[0] || sa1 != g->sa[1]) {
|
||||
printf("---- %s \n", g->name.c_str());
|
||||
exit(-1);
|
||||
printf("WRONG-SA: %s \n", g->name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 false;
|
||||
}
|
||||
|
||||
if(this->flip_total_cnt != flip_total_cnt || this->stem_total_cnt != stem_total_cnt || this->fault_total_cnt != fault_total_cnt) {
|
||||
printf("CIRCUIT CHECK FAILED!\n");
|
||||
printf("[wrong] flip_cnt: %d, stem_cnt: %d, fault_cnt:%d\n", this->flip_total_cnt, this->stem_total_cnt, this->fault_total_cnt);
|
||||
printf("[right] flip_cnt: %d, stem_cnt: %d, fault_cnt:%d\n", flip_total_cnt, stem_total_cnt, fault_total_weight);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
13
circuit.h
13
circuit.h
@ -3,6 +3,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <queue>
|
||||
|
||||
using ll = long long;
|
||||
@ -23,8 +24,6 @@ public:
|
||||
std::vector<Gate*> pre_stems;
|
||||
std::vector<Gate*> suc_stems;
|
||||
|
||||
std::vector<Gate*> block;
|
||||
|
||||
std::vector<Gate*> outputs;
|
||||
std::vector<Gate*> inputs;
|
||||
|
||||
@ -61,11 +60,11 @@ void init_stems();
|
||||
|
||||
// local search
|
||||
|
||||
std::vector<int> local_search(const std::vector<Fault*> &faults);
|
||||
bool local_search(std::unordered_set<Fault*> &faults);
|
||||
|
||||
// incremental flip struct
|
||||
|
||||
const double SP = 0.05;
|
||||
const double SP = 0.01;
|
||||
|
||||
const int FLIP_INC = 1;
|
||||
const int FLIP_WEIGHT_MAX = 1e9;
|
||||
@ -79,7 +78,7 @@ int* flip_need_update;
|
||||
std::vector<Gate*> flip_update_queue;
|
||||
|
||||
// incremental stem struct
|
||||
const int STEM_INC = 10;
|
||||
const int STEM_INC = 100;
|
||||
const int STEM_WEIGHT_MAX = 1e9;
|
||||
ll stem_total_weight;
|
||||
int stem_total_cnt;
|
||||
@ -87,14 +86,14 @@ int* stem_weight;
|
||||
int* stem_satisfied;
|
||||
|
||||
const int FAULT_INC = 1;
|
||||
const int FAULT_WEIGHT_MAX = 100;
|
||||
const int FAULT_WEIGHT_MAX = 20;
|
||||
ll fault_total_weight;
|
||||
int fault_total_cnt;
|
||||
int** fault_weight;
|
||||
int** fault_detected;
|
||||
|
||||
void ls_init_circuit();
|
||||
void ls_init_weight(const std::vector<Fault*> &faults);
|
||||
void ls_init_weight(const std::unordered_set<Fault*> &faults);
|
||||
void ls_update_weight();
|
||||
void ls_init_data_structs();
|
||||
|
||||
|
111
ls.cpp
111
ls.cpp
@ -6,7 +6,7 @@
|
||||
#include <algorithm>
|
||||
#include "assert.h"
|
||||
|
||||
std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) {
|
||||
bool Circuit::local_search(std::unordered_set<Fault*> &faults) {
|
||||
|
||||
// 初始化并重置所有 ls 数据结构
|
||||
ls_init_data_structs();
|
||||
@ -21,12 +21,6 @@ std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) {
|
||||
|
||||
while(true) {
|
||||
|
||||
if(stem_total_cnt == stems.size() && flip_total_cnt == 0) {
|
||||
printf("FIND SOLUTION!\n");
|
||||
printf("[SOL] flip: %lld, stem: %lld, fault:%lld. flip_cnt: %lld, stem_cnt: %lld, fault_cnt:%lld\n", flip_total_weight, stem_total_weight, fault_total_weight, flip_total_cnt, stem_total_cnt, fault_total_cnt);
|
||||
break;
|
||||
}
|
||||
|
||||
Gate* stem = nullptr;
|
||||
ll max_score = 0;
|
||||
|
||||
@ -57,8 +51,8 @@ std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) {
|
||||
}
|
||||
|
||||
if(max_score > 0) {
|
||||
printf("FLIP: %s\n", stem->name.c_str());
|
||||
printf("[LS] flip: %lld, stem: %lld, fault:%lld. flip_cnt: %lld, stem_cnt: %lld, fault_cnt:%lld\n", flip_total_weight, stem_total_weight, fault_total_weight, flip_total_cnt, stem_total_cnt, fault_total_cnt);
|
||||
// printf("FLIP: %s\n", stem->name.c_str());
|
||||
printf("[LS] flip: %lld, stem: %lld, fault:%lld. flip_cnt: %d, stem_cnt: %d, fault_cnt:%d\n", flip_total_weight, stem_total_weight, fault_total_weight, flip_total_cnt, stem_total_cnt, fault_total_cnt);
|
||||
ls_flip(stem);
|
||||
|
||||
CC[stem->id] = 0;
|
||||
@ -84,19 +78,12 @@ std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) {
|
||||
ls_update(g);
|
||||
}
|
||||
|
||||
std::queue<Gate*> q;
|
||||
std::unordered_map<Gate*, bool> used;
|
||||
for(Gate* pi : PIs) {
|
||||
used[pi] = true;
|
||||
q.push(pi);
|
||||
if(stem_total_cnt == stems.size() && flip_total_cnt == 0) {
|
||||
printf("FIND SOLUTION!\n");
|
||||
printf("[SOL] flip: %lld, stem: %lld, fault:%lld. flip_cnt: %d, stem_cnt: %d, fault_cnt:%d\n", flip_total_weight, stem_total_weight, fault_total_weight, flip_total_cnt, stem_total_cnt, fault_total_cnt);
|
||||
break;
|
||||
}
|
||||
|
||||
// while(!q.empty()) {
|
||||
|
||||
// }
|
||||
|
||||
// assert(flip_total_cnt == 0);
|
||||
|
||||
std::vector<Gate*> candidates;
|
||||
for(Gate *g : stems) {
|
||||
if(g->isPO) continue;
|
||||
@ -136,29 +123,45 @@ std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) {
|
||||
ls_update(g);
|
||||
}
|
||||
|
||||
//print_gates();
|
||||
|
||||
return std::vector<int>();
|
||||
static int original_faults = -1;
|
||||
if(original_faults == - 1) {
|
||||
original_faults = faults.size();
|
||||
}
|
||||
static int pattern = 0;
|
||||
|
||||
std::unordered_set<Fault*> tmp = faults;
|
||||
|
||||
for(Fault* f : tmp) {
|
||||
if(f->gate->sa[f->type]) {
|
||||
faults.erase(f);
|
||||
}
|
||||
}
|
||||
|
||||
if(tmp.size() == faults.size()) pattern--;
|
||||
|
||||
printf("coverage: %.4f\tpattern: %d\tbefore: %d\tnow: %d\n", (double)(original_faults - faults.size()) / (original_faults), ++pattern, tmp.size(), faults.size());
|
||||
|
||||
//if(tmp.size() == faults.size()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Circuit::ls_update_weight() {
|
||||
if(rand() % 10 < 3) {
|
||||
|
||||
for(Gate* g : gates) {
|
||||
|
||||
if(g->stem && stem_satisfied[g->id] && (stem_weight[g->id] - STEM_INC > 1)) {
|
||||
stem_weight[g->id] -= STEM_INC;
|
||||
stem_total_weight -= STEM_INC;
|
||||
|
||||
for(Gate* suc : g->suc_stems) {
|
||||
if(!stem_satisfied[suc->id]) {
|
||||
stem_weight[suc->id] += STEM_INC;
|
||||
}
|
||||
}
|
||||
//stem_total_weight += STEM_INC;
|
||||
}
|
||||
}
|
||||
|
||||
if(rand() % 10000 <= SP * 10000) {
|
||||
// for(Gate* g : gates) {
|
||||
// if(g->stem && stem_satisfied[g->id] && (stem_weight[g->id] - STEM_INC >= 1)) {
|
||||
// stem_weight[g->id] -= STEM_INC;
|
||||
// for(Gate* suc : g->suc_stems) {
|
||||
// if(stem_weight[suc->id] + STEM_INC <= STEM_WEIGHT_MAX) {
|
||||
// stem_weight[suc->id] += STEM_INC;
|
||||
// if(!stem_satisfied[suc->id]) {
|
||||
// stem_total_weight += STEM_INC;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
for(Gate* g : gates) {
|
||||
if(flip_need_update[g->id] && (flip_weight[g->id] + FLIP_INC < FLIP_WEIGHT_MAX)) {
|
||||
@ -168,15 +171,25 @@ void Circuit::ls_update_weight() {
|
||||
|
||||
if(g->stem && !stem_satisfied[g->id] && (stem_weight[g->id] + STEM_INC < STEM_WEIGHT_MAX)) {
|
||||
stem_weight[g->id] += STEM_INC;
|
||||
stem_total_weight += STEM_INC;
|
||||
|
||||
for(Gate* suc : g->suc_stems) {
|
||||
if(stem_weight[suc->id] - STEM_INC > 1) {
|
||||
stem_weight[suc->id] -= STEM_INC;
|
||||
if(stem_satisfied[suc->id]) {
|
||||
if(!stem_satisfied[suc->id]) {
|
||||
stem_total_weight -= STEM_INC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(Gate* pre : g->pre_stems) {
|
||||
if(stem_weight[pre->id] + STEM_INC < STEM_WEIGHT_MAX) {
|
||||
stem_weight[pre->id] += STEM_INC;
|
||||
if(!stem_satisfied[pre->id]) {
|
||||
stem_total_weight += STEM_INC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!g->sa[0] && fault_weight[g->id][0] > 0 && (fault_weight[g->id][0] + FAULT_INC < FAULT_WEIGHT_MAX)) {
|
||||
@ -216,7 +229,7 @@ ll Circuit::ls_pick_score(Gate* stem) {
|
||||
}
|
||||
|
||||
ll Circuit::ls_score() {
|
||||
ll score = - flip_total_weight + stem_total_weight + fault_total_weight;
|
||||
ll score = -flip_total_weight -stem_total_weight + fault_total_weight;
|
||||
return score;
|
||||
}
|
||||
|
||||
@ -230,13 +243,13 @@ void Circuit::ls_block_recal(Gate* 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_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_weight += stem_weight[stem->id];
|
||||
stem_total_cnt -= 1;
|
||||
}
|
||||
|
||||
@ -296,13 +309,13 @@ void Circuit::ls_block_recal(Gate* 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_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_weight += stem_weight[stem->id];
|
||||
stem_total_cnt -= 1;
|
||||
}
|
||||
}
|
||||
@ -381,9 +394,10 @@ void Circuit::ls_block_recal(Gate* stem) {
|
||||
}
|
||||
}
|
||||
|
||||
void Circuit::ls_init_weight(const std::vector<Fault*> &faults) {
|
||||
void Circuit::ls_init_weight(const std::unordered_set<Fault*> &faults) {
|
||||
for(Gate* s : stems) {
|
||||
stem_weight[s->id] = 1;
|
||||
stem_total_weight += stem_weight[s->id];
|
||||
}
|
||||
for(Fault* f : faults) {
|
||||
fault_weight[f->gate->id][f->type] = 1;
|
||||
@ -398,6 +412,11 @@ void Circuit::ls_init_circuit() {
|
||||
// pi->value = rand() % 2;
|
||||
// }
|
||||
|
||||
for(Gate* g : gates) {
|
||||
g->sa[0] = 0;
|
||||
g->sa[1] = 0;
|
||||
}
|
||||
|
||||
for(Gate* s : stems) {
|
||||
s->value = rand() % 2;
|
||||
}
|
||||
|
23
main.cpp
23
main.cpp
@ -28,20 +28,25 @@ int main(int args, char* argv[]) {
|
||||
printf("Stem:\t%ld\n", circuit->stems.size());
|
||||
printf("================================ \n");
|
||||
|
||||
std::vector<Fault*> faults;
|
||||
std::unordered_set<Fault*> faults;
|
||||
|
||||
// init faults
|
||||
for(auto stem : circuit->stems) {
|
||||
faults.push_back(new Fault(stem, Fault::SA0));
|
||||
faults.push_back(new Fault(stem, Fault::SA1));
|
||||
for(auto g : circuit->gates) {
|
||||
faults.insert(new Fault(g, Fault::SA0));
|
||||
faults.insert(new Fault(g, Fault::SA1));
|
||||
}
|
||||
|
||||
auto pattern = circuit->local_search(faults);
|
||||
while(true) {
|
||||
bool ls = circuit->local_search(faults);
|
||||
bool is_valid = circuit->is_valid_circuit();
|
||||
printf("checking valid circuit ...");
|
||||
printf(" result: %d.\n", is_valid);
|
||||
if(!ls) break;
|
||||
if(!is_valid) break;
|
||||
if(faults.size() == 0) break;
|
||||
}
|
||||
|
||||
printf("checking valid circuit ...");
|
||||
printf(" result: %d.\n", circuit->is_valid_circuit());
|
||||
|
||||
printf("[final] flip: %d, stem: %d, fault:%d\n", circuit->flip_total_weight, circuit->stem_total_weight, circuit->fault_total_weight);
|
||||
//printf("[final] flip: %d, stem: %d, fault:%d\n", circuit->flip_total_weight, circuit->stem_total_weight, circuit->fault_total_weight);
|
||||
|
||||
return 0;
|
||||
}
|
2
makefile
2
makefile
@ -7,7 +7,7 @@
|
||||
#编译工具用g++,以同时支持C和C++程序,以及二者的混合编译
|
||||
CC=g++
|
||||
|
||||
CPPFLAGS=-O3 -std=c++17 -g
|
||||
CPPFLAGS=-O3 -std=c++17
|
||||
|
||||
#使用$(winldcard *.c)来获取工作目录下的所有.c文件的列表
|
||||
#sources:=main.cpp command.c
|
||||
|
@ -1,2 +0,0 @@
|
||||
[H[2J[3Jset -e; rm -f ls.d; g++ -MM -O3 -std=c++17 -g ls.cpp > ls.d.$$; sed 's,\(ls\)\.o[ :]*,\1.o ls.d : ,g' < ls.d.$$ > ls.d; rm -f ls.d.$$
|
||||
g++ -O3 -std=c++17 -g -c ls.cpp -o ls.o
|
@ -34,7 +34,7 @@ void Circuit::parse_from_file(const char *filename) {
|
||||
}
|
||||
|
||||
// buf 10MB
|
||||
file.rdbuf()->pubsetbuf(0, 10 *1024 * 1024);
|
||||
file.rdbuf()->pubsetbuf(0, 10 * 1024 * 1024);
|
||||
|
||||
std::vector<std::string> bufPO;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user