|
@ -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; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|