Browse Source

refactor: code structure of fast cal module

master
Dnomd343 3 weeks ago
parent
commit
f93deb908f
  1. 7
      src/core/benchmark/fast_cal.cc
  2. 128
      src/core/fast_cal/fast_cal.h
  3. 186
      src/core/fast_cal/internal/cal_core.cc
  4. 37
      src/core/fast_cal/internal/demo.cc
  5. 193
      src/core/fast_cal/internal/fast_cal.cc
  6. 10
      src/core/fast_cal/internal/fast_cal.inl
  7. 3
      src/core/fast_cal/internal/layer_queue.inl
  8. 43
      src/core/fast_cal/layer_queue.h
  9. 42
      src/core/main.cc

7
src/core/benchmark/fast_cal.cc

@ -8,15 +8,18 @@
using klotski::codec::CommonCode;
using klotski::fast_cal::FastCalPro;
static void FastCalBenchmark(benchmark::State &state) {
auto code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code();
// auto code = CommonCode::unsafe_create(0x4FEA13400).to_raw_code();
for (auto _ : state) {
// auto fc = FastCal(code);
auto fc = FastCalPro(code);
benchmark::DoNotOptimize(fc.solve());
// benchmark::DoNotOptimize(fc.demo());
benchmark::DoNotOptimize(FastCal_demo(code));
// benchmark::DoNotOptimize(FastCal_demo(code));
// auto tmp = klotski::cases::Group_extend(code);
}

128
src/core/fast_cal/fast_cal.h

@ -4,11 +4,11 @@
#pragma once
#include <queue>
// #include <queue>
#include <vector>
#include <cstdint>
#include <functional>
#include <unordered_map>
// #include <unordered_map>
#include "mover/mover.h"
#include "raw_code/raw_code.h"
@ -21,91 +21,60 @@
#include <parallel_hashmap/phmap.h>
using klotski::codec::RawCode;
using klotski::mover::MaskMover;
// using klotski::codec::RawCode;
// using klotski::mover::MaskMover;
// TODO: using prime number
const uint32_t FC_MAP_RESERVE = 65536 * 8;
// const uint32_t FC_MAP_RESERVE = 65536 * 8;
/// FastCal not found -> return invalid raw code
const RawCode FC_NOT_FOUND = RawCode::unsafe_create(0);
// const RawCode FC_NOT_FOUND = RawCode::unsafe_create(0);
class FastCal {
public:
typedef std::function<bool(uint64_t)> match_t;
// class FastCal {
// public:
// typedef std::function<bool(uint64_t)> match_t;
/// setting root code
void set_root(const RawCode &code);
explicit FastCal(const RawCode &code);
// void set_root(const RawCode &code);
// explicit FastCal(const RawCode &code);
/// backtrack functions
int step_num(const RawCode &code);
std::vector<RawCode> backtrack(const RawCode &code);
// int step_num(const RawCode &code);
// std::vector<RawCode> backtrack(const RawCode &code);
/// BFS search functions
void build();
RawCode solve();
std::vector<RawCode> furthest();
std::vector<RawCode> solve_multi();
RawCode target(const match_t &match);
std::vector<RawCode> target_multi(const match_t &match);
// void build();
// RawCode solve();
// std::vector<RawCode> furthest();
// std::vector<RawCode> solve_multi();
// RawCode target(const match_t &match);
// std::vector<RawCode> target_multi(const match_t &match);
RawCode demo();
// RawCode demo();
/// static BFS search functions
static std::vector<RawCode> resolve(const RawCode &start);
static std::vector<std::vector<RawCode>> to_furthest(const RawCode &start);
static std::vector<std::vector<RawCode>> resolve_multi(const RawCode &start);
static std::vector<RawCode> search(const RawCode &start, const match_t &match);
static std::vector<std::vector<RawCode>> search_multi(const RawCode &start, const match_t &match);
private:
struct fast_cal_t {
uint64_t code;
uint64_t mask;
fast_cal_t *last;
};
uint64_t root;
std::queue<fast_cal_t*> cache;
std::unordered_map<uint64_t, fast_cal_t> cases;
inline MaskMover init(uint64_t code);
void new_case(uint64_t code, uint64_t mask);
};
RawCode FastCal_demo(RawCode code);
namespace klotski {
template <typename T>
class LayerQueue {
public:
LayerQueue(size_t reserve, std::initializer_list<T> first_layer);
// static std::vector<RawCode> resolve(const RawCode &start);
// static std::vector<std::vector<RawCode>> to_furthest(const RawCode &start);
// static std::vector<std::vector<RawCode>> resolve_multi(const RawCode &start);
// static std::vector<RawCode> search(const RawCode &start, const match_t &match);
// static std::vector<std::vector<RawCode>> search_multi(const RawCode &start, const match_t &match);
void emplace(T item);
// private:
// struct fast_cal_t {
// uint64_t code;
// uint64_t mask;
// fast_cal_t *last;
// };
T current() const;
// uint64_t root;
// std::queue<fast_cal_t*> cache;
// std::unordered_map<uint64_t, fast_cal_t> cases;
void next();
// inline MaskMover init(uint64_t code);
// void new_case(uint64_t code, uint64_t mask);
// };
[[nodiscard]] bool is_ending() const;
[[nodiscard]] bool is_new_layer() const;
std::vector<T> layer_cases() const;
private:
size_t queue_begin_ {0};
size_t queue_end_ {0};
size_t layer_begin_ {0};
size_t layer_end_ {0};
std::vector<T> data_ {};
};
} // namespace klotski
#include "layer_queue.h"
namespace klotski::fast_cal {
@ -113,26 +82,30 @@ class FastCalPro {
public:
FastCalPro() = delete;
explicit FastCalPro(RawCode raw_code);
explicit FastCalPro(codec::RawCode raw_code);
// ------------------------------------------------------------------------------------- //
// TODO: add global build
/// Calculate the case with minimum steps.
std::optional<RawCode> solve();
std::optional<codec::RawCode> solve();
/// Calculate the cases with maximum steps.
std::vector<RawCode> furthest();
std::vector<codec::RawCode> furthest();
/// Calculate all of the minimum-step cases.
std::vector<RawCode> solve_multi();
std::vector<codec::RawCode> solve_multi();
/// Calculate the first case that meets the requirement.
std::optional<RawCode> achieve(std::function<bool(RawCode)> &&match);
std::optional<codec::RawCode> search(std::function<bool(codec::RawCode)> &&match);
// ------------------------------------------------------------------------------------- //
/// Backtrack the shortest path from specified case.
std::vector<RawCode> backtrack(RawCode code);
std::vector<codec::RawCode> backtrack(codec::RawCode code) const;
// std::vector<std::vector<codec::RawCode>> export_layers() const;
// ------------------------------------------------------------------------------------- //
@ -140,7 +113,7 @@ private:
// ------------------------------------------------------------------------------------- //
/// Search next step cases and pop current.
KLSK_INLINE void spawn_next(MaskMover &mover);
KLSK_INLINE void spawn_next(mover::MaskMover &mover);
/// Try to emplace the searched info into the cache.
KLSK_INLINE bool try_emplace(uint64_t code, uint64_t mask);
@ -160,5 +133,6 @@ private:
} // namespace klotski::fast_cal
#include "internal/layer_queue.inl"
// klotski::codec::RawCode FastCal_demo(klotski::codec::RawCode code);
#include "internal/fast_cal.inl"

186
src/core/fast_cal/internal/cal_core.cc

@ -1,105 +1,105 @@
#include "fast_cal/fast_cal.h"
MaskMover FastCal::init(uint64_t code) { // initialize process
/// reset working data
cases.clear();
cases.reserve(FC_MAP_RESERVE); // hashmap pre-reserve
std::queue<fast_cal_t*>{}.swap(cache);
/// insert root node
cache.emplace(&cases.emplace(code, fast_cal_t {
.code = code,
.mask = 0,
.last = nullptr, // without parent node
}).first->second);
/// import klotski mover
return MaskMover(
[this](auto &&code, auto &&mask) { // lambda as function pointer
new_case(std::forward<decltype(code)>(code), std::forward<decltype(mask)>(mask));
}
);
}
// MaskMover FastCal::init(uint64_t code) { // initialize process
// /// reset working data
// cases.clear();
// cases.reserve(FC_MAP_RESERVE); // hashmap pre-reserve
// std::queue<fast_cal_t*>{}.swap(cache);
//
// /// insert root node
// cache.emplace(&cases.emplace(code, fast_cal_t {
// .code = code,
// .mask = 0,
// .last = nullptr, // without parent node
// }).first->second);
//
// /// import klotski mover
// return MaskMover(
// [this](auto &&code, auto &&mask) { // lambda as function pointer
// new_case(std::forward<decltype(code)>(code), std::forward<decltype(mask)>(mask));
// }
// );
// }
/// callback function for new case
void FastCal::new_case(uint64_t code, uint64_t mask) {
auto current = cases.find(code);
if (current != cases.end()) { // find existed case
current->second.mask |= mask; // update mask info
return;
}
cache.emplace(&cases.emplace(code, fast_cal_t { // record new case
.code = code,
.mask = mask,
.last = cache.front(), // link parent case
}).first->second);
}
// void FastCal::new_case(uint64_t code, uint64_t mask) {
// auto current = cases.find(code);
// if (current != cases.end()) { // find existed case
// current->second.mask |= mask; // update mask info
// return;
// }
// cache.emplace(&cases.emplace(code, fast_cal_t { // record new case
// .code = code,
// .mask = mask,
// .last = cache.front(), // link parent case
// }).first->second);
// }
/// build total search tree
void FastCal::build() {
auto core = init(root);
while (!cache.empty()) {
core.next_cases(cache.front()->code, cache.front()->mask);
cache.pop();
}
}
// void FastCal::build() {
// auto core = init(root);
// while (!cache.empty()) {
// core.next_cases(cache.front()->code, cache.front()->mask);
// cache.pop();
// }
// }
/// found first matched target
RawCode FastCal::target(const match_t &match) {
auto core = init(root);
while (!cache.empty()) {
if (match(cache.front()->code)) {
return RawCode::unsafe_create(cache.front()->code); // match target
}
core.next_cases(cache.front()->code, cache.front()->mask);
cache.pop();
}
return FC_NOT_FOUND; // target not found
}
// RawCode FastCal::target(const match_t &match) {
// auto core = init(root);
// while (!cache.empty()) {
// if (match(cache.front()->code)) {
// return RawCode::unsafe_create(cache.front()->code); // match target
// }
// core.next_cases(cache.front()->code, cache.front()->mask);
// cache.pop();
// }
// return FC_NOT_FOUND; // target not found
// }
/// found all of the furthest cases
std::vector<RawCode> FastCal::furthest() {
auto core = init(root);
auto layer_end = cache.back();
std::vector<RawCode> layer_cases;
/// start BFS search
while (!cache.empty()) {
core.next_cases(cache.front()->code, cache.front()->mask);
layer_cases.emplace_back(
RawCode::unsafe_create(cache.front()->code) // record layer cases
);
if (cache.front() == layer_end) { // reach layer ending
if (cache.size() == 1) {
break; // stop loop at last layer
}
layer_cases.clear();
layer_end = cache.back(); // reset layer ending
}
cache.pop();
}
return layer_cases; // release the latest layer cases
}
// std::vector<RawCode> FastCal::furthest() {
// auto core = init(root);
// auto layer_end = cache.back();
// std::vector<RawCode> layer_cases;
// /// start BFS search
// while (!cache.empty()) {
// core.next_cases(cache.front()->code, cache.front()->mask);
// layer_cases.emplace_back(
// RawCode::unsafe_create(cache.front()->code) // record layer cases
// );
// if (cache.front() == layer_end) { // reach layer ending
// if (cache.size() == 1) {
// break; // stop loop at last layer
// }
// layer_cases.clear();
// layer_end = cache.back(); // reset layer ending
// }
// cache.pop();
// }
// return layer_cases; // release the latest layer cases
// }
/// found multi-targets matched in first same layer
std::vector<RawCode> FastCal::target_multi(const match_t &match) {
auto core = init(root);
auto layer_end = cache.back();
std::vector<RawCode> matched; // matched list
/// start BFS search
while (!cache.empty()) {
if (match(cache.front()->code)) { // match target
matched.emplace_back(
RawCode::unsafe_create(cache.front()->code) // record matched cases
);
}
core.next_cases(cache.front()->code, cache.front()->mask);
if (cache.front() == layer_end) { // reach layer ending
if (!matched.empty()) {
return matched; // stop at first matched layer
}
layer_end = cache.back(); // reset layer ending
}
cache.pop();
}
return std::vector<RawCode>{}; // no target found
}
// std::vector<RawCode> FastCal::target_multi(const match_t &match) {
// auto core = init(root);
// auto layer_end = cache.back();
// std::vector<RawCode> matched; // matched list
// /// start BFS search
// while (!cache.empty()) {
// if (match(cache.front()->code)) { // match target
// matched.emplace_back(
// RawCode::unsafe_create(cache.front()->code) // record matched cases
// );
// }
// core.next_cases(cache.front()->code, cache.front()->mask);
// if (cache.front() == layer_end) { // reach layer ending
// if (!matched.empty()) {
// return matched; // stop at first matched layer
// }
// layer_end = cache.back(); // reset layer ending
// }
// cache.pop();
// }
// return std::vector<RawCode>{}; // no target found
// }

37
src/core/fast_cal/internal/demo.cc

@ -40,7 +40,7 @@ std::optional<RawCode> FastCalPro::solve() {
return std::nullopt;
}
std::optional<RawCode> FastCalPro::achieve(std::function<bool(RawCode)> &&match) {
std::optional<RawCode> FastCalPro::search(std::function<bool(RawCode)> &&match) {
// TODO: check root case
uint64_t target = 0;
@ -96,7 +96,7 @@ std::vector<RawCode> FastCalPro::furthest() {
}
}
std::vector<RawCode> FastCalPro::backtrack(RawCode code) {
std::vector<RawCode> FastCalPro::backtrack(RawCode code) const {
if (const auto match = cases_.find(code.unwrap()); match == cases_.end()) {
return {}; // case not found
}
@ -109,15 +109,30 @@ std::vector<RawCode> FastCalPro::backtrack(RawCode code) {
return path;
}
RawCode FastCal_demo(RawCode raw_code) {
klotski::fast_cal::FastCalPro fc {raw_code};
// return fc.solve().value();
// std::vector<std::vector<RawCode>> FastCalPro::export_layers() const {
// auto layer = furthest();
//
// std::vector<std::vector<RawCode>> result;
// result.emplace_back(layer);
//
// for (auto code : layer) {
// std::cout << code << std::endl;
// }
auto tmp = fc.solve();
// std::cout << tmp.value().to_common_code() << std::endl;
// return {};
// }
// RawCode FastCal_demo(RawCode raw_code) {
// FastCalPro fc {raw_code};
// return fc.solve().value();
// auto tmp = fc.solve();
// std::cout << tmp.value().to_common_code() << std::endl;
auto path = fc.backtrack(tmp.value());
std::cout << path.size() << std::endl;
// auto path = fc.backtrack(tmp.value());
// std::cout << path.size() << std::endl;
// fc.export_layers();
// auto tmp = fc.solve_multi();
// for (const auto x : tmp) {
@ -134,5 +149,5 @@ RawCode FastCal_demo(RawCode raw_code) {
// });
// std::cout << tmp.value().to_common_code() << std::endl;
return RawCode::unsafe_create(0);
}
// return RawCode::unsafe_create(0);
// }

193
src/core/fast_cal/internal/fast_cal.cc

@ -8,133 +8,88 @@
#include "group/group.h"
FastCal::FastCal(const RawCode &code) {
this->root = (uint64_t)code;
}
// FastCal::FastCal(const RawCode &code) {
// this->root = (uint64_t)code;
// }
void FastCal::set_root(const RawCode &code) {
this->root = (uint64_t)code;
}
// void FastCal::set_root(const RawCode &code) {
// this->root = (uint64_t)code;
// }
/// klotski resolved -> 2x2 block at address 13 (aka 0xD)
auto resolved = [](uint64_t code) {
return ((code >> (3 * 0xD)) & 0b111) == BLOCK_2x2; // check 2x2 block address
};
// auto resolved = [](uint64_t code) {
// return ((code >> (3 * 0xD)) & 0b111) == BLOCK_2x2; // check 2x2 block address
// };
RawCode FastCal::solve() {
return FastCal::target(resolved);
}
// RawCode FastCal::solve() {
// return FastCal::target(resolved);
// }
RawCode FastCal::demo() {
// std::vector<RawCode> FastCal::solve_multi() {
// return FastCal::target_multi(resolved);
// }
// max_group_size = 25955
// auto reserve = klotski::cases::GroupUnion::from_raw_code(RawCode::unsafe_create(root)).max_group_size();
// std::vector<RawCode> FastCal::resolve(const RawCode &start) {
// return FastCal::search(start, resolved);
// }
cases.reserve(25955); // FAST !!! (about 5ms)
// cases.reserve(32768); // SLOW !!! (about 50ms)
// TODO: using prime number!
std::queue<fast_cal_t*>{}.swap(cache);
cache.emplace(&cases.emplace(root, fast_cal_t {
.code = root,
.mask = 0,
.last = nullptr, // without parent node
}).first->second);
auto core = MaskMover(
[this](uint64_t code, uint64_t mask) { // lambda as function pointer
auto current = cases.find(code);
if (current != cases.end()) { // find existed case
current->second.mask |= mask; // update mask info
return;
}
cache.emplace(&cases.emplace(code, fast_cal_t { // record new case
.code = code,
.mask = mask,
.last = cache.front(), // link parent case
}).first->second);
}
);
while (!cache.empty()) {
if (((cache.front()->code >> (3 * 0xD)) & 0b111) == BLOCK_2x2) {
return RawCode::unsafe_create(cache.front()->code); // match target
}
core.next_cases(cache.front()->code, cache.front()->mask);
cache.pop();
}
return FC_NOT_FOUND; // target not found
}
std::vector<RawCode> FastCal::solve_multi() {
return FastCal::target_multi(resolved);
}
std::vector<RawCode> FastCal::resolve(const RawCode &start) {
return FastCal::search(start, resolved);
}
std::vector<std::vector<RawCode>> FastCal::resolve_multi(const RawCode &start) {
return FastCal::search_multi(start, resolved);
}
// std::vector<std::vector<RawCode>> FastCal::resolve_multi(const RawCode &start) {
// return FastCal::search_multi(start, resolved);
// }
/// backtrack of FastCal tree
int FastCal::step_num(const RawCode &code) {
auto tmp = cases.find((uint64_t)code);
if (tmp == cases.end()) {
return -1; // code not exist
}
int num = 0; // step number
auto node = &tmp->second; // backtrack entry
while ((node = node->last) != nullptr) {
++num;
}
return num;
}
std::vector<RawCode> FastCal::backtrack(const RawCode &code) {
auto tmp = cases.find((uint64_t)code);
if (tmp == cases.end()) {
return std::vector<RawCode>{}; // code not exist
}
auto node = &tmp->second; // backtrack entry
std::vector<RawCode> path; // backtrack path
while (node != nullptr) {
path.emplace_back(RawCode::unsafe_create(node->code)); // record path info
node = node->last;
}
std::reverse(path.begin(), path.end()); // reverse path cases
return path;
}
// int FastCal::step_num(const RawCode &code) {
// auto tmp = cases.find((uint64_t)code);
// if (tmp == cases.end()) {
// return -1; // code not exist
// }
// int num = 0; // step number
// auto node = &tmp->second; // backtrack entry
// while ((node = node->last) != nullptr) {
// ++num;
// }
// return num;
// }
// std::vector<RawCode> FastCal::backtrack(const RawCode &code) {
// auto tmp = cases.find((uint64_t)code);
// if (tmp == cases.end()) {
// return std::vector<RawCode>{}; // code not exist
// }
// auto node = &tmp->second; // backtrack entry
// std::vector<RawCode> path; // backtrack path
// while (node != nullptr) {
// path.emplace_back(RawCode::unsafe_create(node->code)); // record path info
// node = node->last;
// }
// std::reverse(path.begin(), path.end()); // reverse path cases
// return path;
// }
/// static BFS search functions
std::vector<std::vector<RawCode>> FastCal::to_furthest(const RawCode &start) {
auto fc = FastCal(start);
std::vector<std::vector<RawCode>> result;
for (const auto &furthest : fc.furthest()) {
result.emplace_back(fc.backtrack(furthest)); // backtrack every furthest cases
}
return result;
}
std::vector<RawCode> FastCal::search(const RawCode &start, const match_t &match) {
auto fc = FastCal(start);
auto result = fc.target(match);
if (result == FC_NOT_FOUND) {
return std::vector<RawCode>{}; // target not matched
}
return fc.backtrack(result); // backtrack target path
}
std::vector<std::vector<RawCode>> FastCal::search_multi(const RawCode &start, const match_t &match) {
auto fc = FastCal(start);
std::vector<std::vector<RawCode>> result;
for (const auto &target : fc.target_multi(match)) {
result.emplace_back(fc.backtrack(target)); // backtrack every target
}
return result;
}
// std::vector<std::vector<RawCode>> FastCal::to_furthest(const RawCode &start) {
// auto fc = FastCal(start);
// std::vector<std::vector<RawCode>> result;
// for (const auto &furthest : fc.furthest()) {
// result.emplace_back(fc.backtrack(furthest)); // backtrack every furthest cases
// }
// return result;
// }
// std::vector<RawCode> FastCal::search(const RawCode &start, const match_t &match) {
// auto fc = FastCal(start);
// auto result = fc.target(match);
// if (result == FC_NOT_FOUND) {
// return std::vector<RawCode>{}; // target not matched
// }
// return fc.backtrack(result); // backtrack target path
// }
// std::vector<std::vector<RawCode>> FastCal::search_multi(const RawCode &start, const match_t &match) {
// auto fc = FastCal(start);
// std::vector<std::vector<RawCode>> result;
// for (const auto &target : fc.target_multi(match)) {
// result.emplace_back(fc.backtrack(target)); // backtrack every target
// }
// return result;
// }

10
src/core/fast_cal/internal/fast_cal.inl

@ -2,10 +2,10 @@
namespace klotski::fast_cal {
inline FastCalPro::FastCalPro(RawCode raw_code) : codes_(cases::GroupUnion::from_raw_code(raw_code).max_group_size(), {raw_code.unwrap()}) {
// auto reserve = cases::GroupUnion::from_raw_code(raw_code).max_group_size();
cases_.reserve(static_cast<size_t>(25955 * 1.56));
// cases_.reserve(static_cast<size_t>(reserve * 1.56));
inline FastCalPro::FastCalPro(codec::RawCode raw_code) : codes_(cases::GroupUnion::from_raw_code(raw_code).max_group_size(), {raw_code.unwrap()}) {
auto reserve = cases::GroupUnion::from_raw_code(raw_code).max_group_size();
// cases_.reserve(static_cast<size_t>(25955 * 1.56));
cases_.reserve(static_cast<size_t>(reserve * 1.56));
cases_.emplace(raw_code, data_t {0, 0}); // without mask
}
@ -22,7 +22,7 @@ inline KLSK_INLINE bool FastCalPro::try_emplace(uint64_t code, uint64_t mask) {
return true;
}
inline KLSK_INLINE void FastCalPro::spawn_next(MaskMover &mover) {
inline KLSK_INLINE void FastCalPro::spawn_next(mover::MaskMover &mover) {
auto curr = codes_.current();
mover.next_cases(curr, cases_.find(curr)->second.mask);
codes_.next();

3
src/core/fast_cal/internal/layer_queue.inl

@ -9,6 +9,8 @@ inline LayerQueue<T>::LayerQueue(size_t reserve, std::initializer_list<T> first_
emplace(x);
}
layer_end_ = first_layer.size();
layers_.reserve(139);
layers_.emplace_back(0, layer_end_);
}
template <typename T>
@ -28,6 +30,7 @@ void LayerQueue<T>::next() {
if (queue_begin_ == layer_end_ && !is_ending()) {
layer_begin_ = layer_end_;
layer_end_ = queue_end_;
layers_.emplace_back(layer_begin_, layer_end_);
}
}

43
src/core/fast_cal/layer_queue.h

@ -0,0 +1,43 @@
/// Klotski Engine by Dnomd343 @2024
#pragma once
#include <vector>
#include <cstdint>
namespace klotski {
template <typename T>
class LayerQueue {
public:
LayerQueue(size_t reserve, std::initializer_list<T> first_layer);
void emplace(T item);
T current() const;
void next();
[[nodiscard]] bool is_ending() const;
[[nodiscard]] bool is_new_layer() const;
std::vector<T> layer_cases() const;
// TODO: allow export all layers
private:
size_t queue_begin_ {0};
size_t queue_end_ {0};
size_t layer_begin_ {0};
size_t layer_end_ {0};
std::vector<T> data_ {};
std::vector<std::pair<size_t, size_t>> layers_ {};
};
} // namespace klotski
#include "internal/layer_queue.inl"

42
src/core/main.cc

@ -47,46 +47,8 @@ int main() {
const auto start = std::chrono::system_clock::now();
auto code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code();
for (int i = 0; i < 100; ++i) {
// FastCal fc {code};
// fc.solve();
// klotski::cases::Group_extend(code);
FastCal_demo(code);
break;
}
// for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) {
// auto group_union = GroupUnion::unsafe_create(type_id);
// for (uint32_t pattern_id = 0; pattern_id < group_union.pattern_num(); ++pattern_id) {
// std::cout << std::format("[{}, {}]\n", type_id, pattern_id);
// auto seed = CommonCode::unsafe_create(PATTERN_DATA[PATTERN_OFFSET[type_id] + pattern_id] >> 23);
//
// double coff = 1.0;
// double last_val = -1;
// while (true) {
// auto val = Group_load_factor(seed.to_raw_code(), coff);
// if (int(val * 1000) != int(last_val * 1000)) {
// std::cout << std::format("{:.2f}, {:.6f}\n", coff, val);
// last_val = val;
// }
// if (coff >= 2.0) {
// break;
// }
// coff += 0.01;
// }
// std::cout << std::endl;
// }
//
// }
// std::cout << Group_load_factor(code, 0.5) << std::endl;
// std::cout << Group_load_factor(code, 0.8) << std::endl;
// std::cout << Group_load_factor(code, 1.0) << std::endl;
// std::cout << Group_load_factor(code, 1.2) << std::endl;
// std::cout << Group_load_factor(code, 1.5) << std::endl;
// std::cout << Group_load_factor(code, 2.0) << std::endl;
// std::cout << Group_load_factor(code, 3.0) << std::endl;
// std::cout << Group_load_factor(code, 5.0) << std::endl;
klotski::fast_cal::FastCalPro fc {code};
std::cout << fc.solve().value() << std::endl;
// for (int i = 0; i < 10000000; ++i) {
// MaskMover mover([](uint64_t code, uint64_t mask) {

Loading…
Cancel
Save