更新了flip
This commit is contained in:
parent
87b8d2ab6c
commit
6861108609
@ -48,7 +48,7 @@ void Circuit::init_topo_index() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(auto in : PIs) {
|
for(auto in : PIs) {
|
||||||
in->topo = topo++;
|
in->id = topo++;
|
||||||
q.push(in);
|
q.push(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ void Circuit::init_topo_index() {
|
|||||||
for(Gate* out : g->outputs) {
|
for(Gate* out : g->outputs) {
|
||||||
ins[out]--;
|
ins[out]--;
|
||||||
if(ins[out] == 0) {
|
if(ins[out] == 0) {
|
||||||
out->topo = topo++;
|
out->id = topo++;
|
||||||
q.push(out);
|
q.push(out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,12 +113,10 @@ bool Circuit::is_valid_circuit() {
|
|||||||
|
|
||||||
if(sa0 != g->sa[0] || sa1 != g->sa[1]) {
|
if(sa0 != g->sa[0] || sa1 != g->sa[1]) {
|
||||||
printf("---- %s \n", g->name.c_str());
|
printf("---- %s \n", g->name.c_str());
|
||||||
//return false;
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
26
circuit.h
26
circuit.h
@ -5,9 +5,11 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
using ll = long long;
|
||||||
|
|
||||||
class Gate {
|
class Gate {
|
||||||
public:
|
public:
|
||||||
int topo;
|
int id;
|
||||||
std::string name;
|
std::string name;
|
||||||
enum Type { AND, NAND, OR, NOR, XOR, XNOR, NOT, BUF, INPUT } type;
|
enum Type { AND, NAND, OR, NOR, XOR, XNOR, NOT, BUF, INPUT } type;
|
||||||
int value;
|
int value;
|
||||||
@ -33,8 +35,7 @@ class Fault {
|
|||||||
public:
|
public:
|
||||||
Gate* gate;
|
Gate* gate;
|
||||||
enum Type { SA0, SA1 } type;
|
enum Type { SA0, SA1 } type;
|
||||||
bool detected;
|
Fault(Gate* gate, Type type):gate(gate),type(type) {}
|
||||||
Fault(Gate* gate, Type type):gate(gate),type(type),detected(0) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Circuit {
|
class Circuit {
|
||||||
@ -57,13 +58,28 @@ bool is_valid_circuit();
|
|||||||
void init_topo_index();
|
void init_topo_index();
|
||||||
void init_stems();
|
void init_stems();
|
||||||
|
|
||||||
|
|
||||||
// local search
|
// local search
|
||||||
|
|
||||||
std::vector<int> local_search(const std::vector<Fault*> &faults);
|
std::vector<int> local_search(const std::vector<Fault*> &faults);
|
||||||
|
|
||||||
|
// incremental flip struct
|
||||||
|
ll flip_total_weight;
|
||||||
|
int* flip_weight;
|
||||||
|
int* flip_need_update;
|
||||||
|
std::vector<Gate*> flip_update_queue;
|
||||||
|
|
||||||
|
// incremental stem struct
|
||||||
|
ll stem_total_weight;
|
||||||
|
int* stem_weight;
|
||||||
|
int* stem_satisfied;
|
||||||
|
|
||||||
|
ll fault_total_weight;
|
||||||
|
int** fault_weight;
|
||||||
|
int** fault_detected;
|
||||||
|
|
||||||
void ls_init_circuit();
|
void ls_init_circuit();
|
||||||
void ls_init_vector(std::vector<Gate*> *vec);
|
void ls_init_weight(const std::vector<Fault*> &faults);
|
||||||
|
void ls_init_data_structs();
|
||||||
void ls_flip(Gate* stem);
|
void ls_flip(Gate* stem);
|
||||||
|
|
||||||
};
|
};
|
96
ls.cpp
96
ls.cpp
@ -7,25 +7,36 @@
|
|||||||
|
|
||||||
std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) {
|
std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) {
|
||||||
|
|
||||||
// local search vector
|
// 初始化并清零所有 ls 数据结构
|
||||||
|
ls_init_data_structs();
|
||||||
|
|
||||||
|
// 赋值初始权重
|
||||||
|
ls_init_weight(faults);
|
||||||
|
|
||||||
|
// 随机生成初始电路
|
||||||
ls_init_circuit();
|
ls_init_circuit();
|
||||||
|
|
||||||
printf("local search!\n");
|
printf("local search!\n");
|
||||||
|
|
||||||
//ls_flip(PIs[0]);
|
//ls_flip(PIs[0]);
|
||||||
|
|
||||||
print_gates();
|
//print_gates();
|
||||||
|
|
||||||
return std::vector<int>();
|
return std::vector<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmp(Gate* a, Gate *b) {
|
bool cmp(Gate* a, Gate *b) {
|
||||||
return a->topo > b->topo;
|
return a->id > b->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Circuit::ls_flip(Gate* stem) {
|
void Circuit::ls_flip(Gate* stem) {
|
||||||
|
|
||||||
printf("flip: %s\n", stem->name.c_str());
|
if(flip_need_update[stem->id]) {
|
||||||
|
flip_need_update[stem->id] = false;
|
||||||
|
flip_total_weight -= flip_weight[stem->id];
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("flip: %s\n", stem->name.c_str());
|
||||||
|
|
||||||
//stem->value = !stem->value;
|
//stem->value = !stem->value;
|
||||||
|
|
||||||
@ -60,13 +71,8 @@ void Circuit::ls_flip(Gate* stem) {
|
|||||||
assert(q.empty());
|
assert(q.empty());
|
||||||
used.clear();
|
used.clear();
|
||||||
|
|
||||||
// update path info
|
|
||||||
std::vector<Gate*> update_list;
|
|
||||||
|
|
||||||
|
|
||||||
for(Gate* stem : suc_stems) {
|
for(Gate* stem : suc_stems) {
|
||||||
q.push(stem);
|
q.push(stem);
|
||||||
//printf("suc: %s\n", stem->name.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while(!q.empty()) {
|
while(!q.empty()) {
|
||||||
@ -100,13 +106,22 @@ void Circuit::ls_flip(Gate* stem) {
|
|||||||
in->sa[1] |= p.second;
|
in->sa[1] |= p.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(in->stem && (in->sa[0] != old_sa[0] || in->sa[0] != old_sa[0])) {
|
if(in->stem && !in->isPI && (in->sa[0] != old_sa[0] || in->sa[1] != old_sa[1])) {
|
||||||
|
|
||||||
|
bool exist = false;
|
||||||
for(Gate* pre : in->pre_stems) {
|
for(Gate* pre : in->pre_stems) {
|
||||||
if(!tmp_used[pre]) {
|
if(flip_need_update[pre->id]) {
|
||||||
tmp_used[pre] = true;
|
exist = true;
|
||||||
tmp.push(pre);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!exist) {
|
||||||
|
Gate* pre = in->pre_stems[0];
|
||||||
|
flip_need_update[pre->id] = true;
|
||||||
|
flip_update_queue.push_back(pre);
|
||||||
|
|
||||||
|
flip_total_weight += flip_weight[pre->id];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//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]);
|
//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]);
|
||||||
@ -119,6 +134,18 @@ void Circuit::ls_flip(Gate* stem) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Circuit::ls_init_weight(const std::vector<Fault*> &faults) {
|
||||||
|
for(Gate* s : stems) {
|
||||||
|
stem_weight[s->id] = 1;
|
||||||
|
}
|
||||||
|
for(Fault* f : faults) {
|
||||||
|
fault_weight[f->gate->id][f->type] = 1;
|
||||||
|
}
|
||||||
|
for(Gate* s: stems) {
|
||||||
|
flip_weight[s->id] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Circuit::ls_init_circuit() {
|
void Circuit::ls_init_circuit() {
|
||||||
// for(auto pi : PIs) {
|
// for(auto pi : PIs) {
|
||||||
// pi->value = rand() % 2;
|
// pi->value = rand() % 2;
|
||||||
@ -129,15 +156,46 @@ void Circuit::ls_init_circuit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(int i=stems.size()-1; i>=0; i--) {
|
for(int i=stems.size()-1; i>=0; i--) {
|
||||||
stems[i]->value = !stems[i]->value;
|
|
||||||
ls_flip(stems[i]);
|
ls_flip(stems[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while(!flip_update_queue.empty()) {
|
||||||
while(!tmp.empty()) {
|
Gate* g = flip_update_queue.back();
|
||||||
Gate* g = tmp.front();
|
flip_update_queue.pop_back();
|
||||||
tmp.pop();
|
flip_need_update[g->id] = false;
|
||||||
tmp_used[g] = false;
|
|
||||||
ls_flip(g);
|
ls_flip(g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Circuit::ls_init_data_structs() {
|
||||||
|
const int MAX_LEN = gates.size() + 1;
|
||||||
|
|
||||||
|
if(flip_weight == nullptr) {
|
||||||
|
flip_weight = new int[MAX_LEN];
|
||||||
|
flip_need_update = new int[MAX_LEN];
|
||||||
|
|
||||||
|
stem_weight = new int[MAX_LEN];
|
||||||
|
stem_satisfied = new int[MAX_LEN];
|
||||||
|
|
||||||
|
fault_weight = new int*[MAX_LEN];
|
||||||
|
for(int i=0; i<MAX_LEN; i++) {
|
||||||
|
fault_weight[i] = new int[2];
|
||||||
|
}
|
||||||
|
fault_detected = new int*[MAX_LEN];
|
||||||
|
for(int i=0; i<MAX_LEN; i++) {
|
||||||
|
fault_detected[i] = new int[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for(int i=0; i<MAX_LEN; i++) {
|
||||||
|
flip_weight[i] = 0;
|
||||||
|
flip_need_update[i] = 0;
|
||||||
|
stem_weight[i] = 0;
|
||||||
|
stem_satisfied[i] = 0;
|
||||||
|
fault_weight[i][0] = 0;
|
||||||
|
fault_weight[i][1] = 0;
|
||||||
|
fault_detected[i][0] = 0;
|
||||||
|
fault_detected[i][1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
main.cpp
22
main.cpp
@ -13,33 +13,33 @@ int main(int args, char* argv[]) {
|
|||||||
|
|
||||||
srand(19260817);
|
srand(19260817);
|
||||||
|
|
||||||
Circuit circuit;
|
Circuit* circuit = new Circuit();
|
||||||
|
|
||||||
printf("parsing file %s ...", argv[1]);
|
printf("parsing file %s ...", argv[1]);
|
||||||
circuit.parse_from_file(argv[1]);
|
circuit->parse_from_file(argv[1]);
|
||||||
circuit.init_stems();
|
circuit->init_stems();
|
||||||
circuit.init_topo_index();
|
circuit->init_topo_index();
|
||||||
printf(" Done.\n");
|
printf(" Done.\n");
|
||||||
|
|
||||||
printf("====== Circuit Statistics ====== \n");
|
printf("====== Circuit Statistics ====== \n");
|
||||||
printf("PI:\t%ld\n", circuit.PIs.size());
|
printf("PI:\t%ld\n", circuit->PIs.size());
|
||||||
printf("PO:\t%ld\n", circuit.POs.size());
|
printf("PO:\t%ld\n", circuit->POs.size());
|
||||||
printf("Gate:\t%ld\n", circuit.name2gate.size());
|
printf("Gate:\t%ld\n", circuit->name2gate.size());
|
||||||
printf("Stem:\t%ld\n", circuit.stems.size());
|
printf("Stem:\t%ld\n", circuit->stems.size());
|
||||||
printf("================================ \n");
|
printf("================================ \n");
|
||||||
|
|
||||||
std::vector<Fault*> faults;
|
std::vector<Fault*> faults;
|
||||||
|
|
||||||
// init faults
|
// init faults
|
||||||
for(auto stem : circuit.stems) {
|
for(auto stem : circuit->stems) {
|
||||||
faults.push_back(new Fault(stem, Fault::SA0));
|
faults.push_back(new Fault(stem, Fault::SA0));
|
||||||
faults.push_back(new Fault(stem, Fault::SA1));
|
faults.push_back(new Fault(stem, Fault::SA1));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pattern = circuit.local_search(faults);
|
auto pattern = circuit->local_search(faults);
|
||||||
|
|
||||||
printf("checking valid circuit ...");
|
printf("checking valid circuit ...");
|
||||||
printf(" result: %d.\n", circuit.is_valid_circuit());
|
printf(" result: %d.\n", circuit->is_valid_circuit());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
40438
output.txt
40438
output.txt
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user