Browse Source

update: backtrack interface of Analyse

master
Dnomd343 2 years ago
parent
commit
1a25d8f30c
  1. 18
      src/analyse/analyse.h
  2. 88
      src/analyse/backtrack.cc

18
src/analyse/analyse.h

@ -43,6 +43,7 @@ private:
void new_case(uint64_t code, uint64_t mask); void new_case(uint64_t code, uint64_t mask);
/// backtrack definitions
public: public:
struct backtrack_t { struct backtrack_t {
uint64_t code; uint64_t code;
@ -50,20 +51,9 @@ public:
std::list<backtrack_t*> last; std::list<backtrack_t*> last;
std::list<backtrack_t*> next; std::list<backtrack_t*> next;
}; };
typedef std::vector<std::unordered_map<uint64_t, backtrack_t>> backtrack_data_t;
void backtrack_demo(const std::vector<uint64_t> &codes); // TODO: try using unordered_set
backtrack_data_t backtrack_demo(const std::vector<uint64_t> &codes);
/// backtrack definitions
// struct backtrack_t {
// uint64_t code;
// uint32_t layer_num;
// uint32_t layer_index;
// std::list<backtrack_t*> next;
// };
// TODO: backtrack for multi-codes
// void backtrack(uint64_t code);
// void backtrack(const std::vector<uint64_t> &raw_code_list);
}; };

88
src/analyse/backtrack.cc

@ -1,104 +1,52 @@
#include <algorithm>
#include "analyse.h" #include "analyse.h"
#include <iostream> #include <iostream>
#include <set> Analyse::backtrack_data_t Analyse::backtrack_demo(const std::vector<uint64_t> &codes) {
#include <unordered_set> /// codes pre-check and sort by steps
#include <algorithm>
#include "common_code.h"
// TODO: using const RawCode& instead of uint64_t
//namespace std {
// template<>
// struct hash<Analyse::backtrack_t> {
// std::size_t operator()(const Analyse::backtrack_t &b) const {
// std::cout << "get hash: " << b.code << std::endl;
// return std::hash<uint64_t>()(b.code);
// }
// };
//
// template<>
// struct equal_to<Analyse::backtrack_t> {
// bool operator()(const Analyse::backtrack_t &b1, const Analyse::backtrack_t &b2) const {
// std::cout << "get eq: " << b1.code << " ? " << b2.code << std::endl;
// return b1.code == b2.code;
// }
// };
//}
void Analyse::backtrack_demo(const std::vector<uint64_t> &codes) {
std::vector<std::vector<analyse_t*>> todos; std::vector<std::vector<analyse_t*>> todos;
for (const auto &code : codes) { for (const auto &code : codes) {
auto c = cases.find(code); auto c = cases.find(code);
if (c == cases.end()) { // invalid input
if (c == cases.end()) { return backtrack_data_t{}; // return empty data
// TODO: invalid input
return;
} }
if (c->second.step >= todos.size()) { if (c->second.step >= todos.size()) {
todos.resize(c->second.step + 1); todos.resize(c->second.step + 1); // enlarge schedule list
} }
todos[c->second.step].emplace_back(&c->second); todos[c->second.step].emplace_back(&c->second);
} }
std::reverse(todos.begin(), todos.end()); // backtrack start from further layer
std::reverse(todos.begin(), todos.end());
struct cache_t { struct cache_t {
analyse_t *a; analyse_t *a;
backtrack_t *b; backtrack_t *b;
}; };
std::queue<cache_t> track_cache; std::queue<cache_t> track_cache;
std::vector<std::unordered_map<uint64_t, backtrack_t>> track_data; Analyse::backtrack_data_t track_data(todos.size());
/// start backtrack process
// track_data.resize(82); // TODO: setting as (max steps + 1)
track_data.resize(todos.size());
// TODO: for diff layer cases, layer_num from big to small -> if found then skip search
for (const auto &todo : todos) { for (const auto &todo : todos) {
if (todo.empty()) { if (todo.empty()) {
continue; continue; // without scheduled cases
} }
std::queue<cache_t>{}.swap(track_cache); // clear track cache
/// clear track cache
std::queue<cache_t>{}.swap(track_cache);
for (const auto c : todo) { for (const auto c : todo) {
/// case already exist -> skip its backtrack
// TODO: if c already exist -> skip
if (track_data[c->step].find(c->code) == track_data[c->step].end()) { if (track_data[c->step].find(c->code) == track_data[c->step].end()) {
track_cache.emplace(cache_t{ track_cache.emplace(cache_t{
.a = c, .a = c,
.b = &track_data[c->step].emplace(c->code, backtrack_t{ .b = &track_data[c->step].emplace(c->code, backtrack_t{
.code = c->code, .code = c->code,
.layer_num = c->step, .layer_num = c->step,
.last = std::list<backtrack_t *>{}, .last = std::list<backtrack_t *>{}, // without parent node
.next = std::list<backtrack_t *>{}, .next = std::list<backtrack_t *>{}, // without sub node
}).first->second, }).first->second,
}); });
} }
} }
/// backtrack until root case
while (!track_cache.empty()) { while (!track_cache.empty()) {
/// handle first element and pop it auto curr = track_cache.front(); // handle first element
auto curr = track_cache.front();
for (auto src : curr.a->src) { // traverse src cases of current node for (auto src : curr.a->src) { // traverse src cases of current node
auto t_src = track_data[src->step].find(src->code); auto t_src = track_data[src->step].find(src->code);
if (t_src != track_data[src->step].end()) { // match src case if (t_src != track_data[src->step].end()) { // match src case
@ -123,8 +71,6 @@ void Analyse::backtrack_demo(const std::vector<uint64_t> &codes) {
} }
track_cache.pop(); track_cache.pop();
} }
} }
@ -152,4 +98,6 @@ void Analyse::backtrack_demo(const std::vector<uint64_t> &codes) {
} }
return track_data;
} }

Loading…
Cancel
Save