Browse Source

feat: add support of multi-solutions

master
Dnomd343 3 weeks ago
parent
commit
b67083c348
  1. 4
      src/core/benchmark/fast_cal.cc
  2. 95
      src/core/fast_cal/internal/demo.cc
  3. 2
      src/core/group/internal/extend.cc
  4. 52
      src/core/main.cc

4
src/core/benchmark/fast_cal.cc

@ -15,8 +15,8 @@ static void FastCalBenchmark(benchmark::State &state) {
for (auto _ : state) {
// auto fc = FastCal(code);
// benchmark::DoNotOptimize(fc.demo());
// benchmark::DoNotOptimize(FastCal_demo(code));
auto tmp = klotski::cases::Group_extend(code);
benchmark::DoNotOptimize(FastCal_demo(code));
// auto tmp = klotski::cases::Group_extend(code);
}
}

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

@ -34,11 +34,16 @@ struct data_t {
template <typename T>
class MyQueue {
public:
// MyQueue() = default;
explicit MyQueue(size_t reserve) {
// vec_.reserve(reserve);
vec_.resize(reserve);
}
// void reserve(size_t size) {
// vec_.resize(size);
// }
void emplace_back(T item) {
// vec_.emplace_back(item);
vec_[iter_] = item;
@ -57,7 +62,7 @@ public:
return offset_ == iter_;
}
private:
//private:
size_t iter_ {0};
size_t offset_ {0};
std::vector<T> vec_ {};
@ -66,9 +71,11 @@ private:
class FCDemo {
public:
explicit FCDemo(RawCode raw_code) : codes_(GroupUnion::from_raw_code(raw_code).max_group_size()) {
// TODO: build codes_ with reserve size
auto reserve = GroupUnion::from_raw_code(raw_code).max_group_size();
// codes_.reserve(reserve);
cases_.reserve(286730);
// cases_.reserve(static_cast<size_t>(reserve * 1.56));
cases_.reserve(static_cast<size_t>(25955 * 1.56));
codes_.emplace_back(raw_code.unwrap());
cases_.emplace(raw_code, data_t {0, 0}); // without mask
}
@ -78,13 +85,11 @@ public:
auto core = MaskMover([this, &result](uint64_t code, uint64_t mask) {
if (const auto match = cases_.find(code); match != cases_.end()) {
match->second.mask |= mask; // update mask
// match.value().mask |= mask; // update mask
return;
}
cases_.emplace(code, data_t {
.mask = mask,
.back = codes_.front(),
// .back = codes_[offset_].unwrap(),
});
codes_.emplace_back(code);
@ -99,56 +104,68 @@ public:
codes_.pop();
if (result != 0) {
// std::cout << cases_.size() << std::endl;
// std::cout << cases_.load_factor() << std::endl;
return RawCode::unsafe_create(result);
}
}
return RawCode::unsafe_create(0);
}
std::vector<RawCode> DoCalMulti() {
// uint64_t result = 0;
bool stop_flag = false;
std::vector<RawCode> results {};
auto core = MaskMover([this, &stop_flag, &results](uint64_t code, uint64_t mask) {
if (const auto match = cases_.find(code); match != cases_.end()) {
match->second.mask |= mask; // update mask
return;
}
cases_.emplace(code, data_t {
.mask = mask,
.back = codes_.front(),
});
codes_.emplace_back(code);
if (((code >> 39) & 0b111) == 0b100) {
stop_flag = true;
// result = code;
results.emplace_back(RawCode::unsafe_create(code));
}
});
std::cout << cases_.load_factor() << std::endl;
size_t layer_end = 1;
return RawCode::unsafe_create(0);
while (!codes_.empty()) {
auto curr = codes_.front();
core.next_cases(curr, cases_.find(curr)->second.mask);
codes_.pop();
// while (offset_ != codes_.size()) {
// auto curr = codes_[offset_].unwrap();
// core.next_cases(curr, cases_.find(curr)->second.mask);
// ++offset_;
//
// if (result != 0) {
// break;
// }
// }
if (codes_.offset_ == layer_end) {
// std::cout << "layer: " << codes_.offset_ << std::endl;
layer_end = codes_.iter_;
if (stop_flag) {
return results;
}
}
// std::vector<RawCode> path;
// auto code = result;
// while (true) {
// if (code == 0) {
// break;
// }
// path.emplace_back(RawCode::unsafe_create(code));
// code = cases_.find(code)->second.back;
// }
// std::reverse(path.begin(), path.end());
// for (auto step : path) {
// std::cout << step << std::endl;
// if (result != 0) {
// return RawCode::unsafe_create(result);
// }
// std::cout << path.size() << std::endl;
// return codes_[offset_];
}
return {};
}
private:
// uint64_t offset_ {0};
MyQueue<uint64_t> codes_;
// absl::flat_hash_map<uint64_t, data_t> cases_; // <code, mask>
// robin_hood::unordered_map<uint64_t, data_t> cases_;
// ankerl::unordered_dense::map<uint64_t, data_t> cases_;
// tsl::robin_map<uint64_t, data_t> cases_;
phmap::flat_hash_map<uint64_t, data_t> cases_;
};
RawCode FastCal_demo(RawCode raw_code) {
FCDemo fc {raw_code};
return fc.DoCal();
// return fc.DoCal();
auto tmp = fc.DoCalMulti();
// for (auto code : tmp) {
// std::cout << code << std::endl;
// }
return tmp[0];
}

2
src/core/group/internal/extend.cc

@ -13,6 +13,8 @@ using klotski::cases::RangesUnion;
using klotski::mover::MaskMover;
using klotski::cases::GroupUnion;
// TODO: maybe we can perf with mirror cases
std::vector<RawCode> klotski::cases::Group_extend(RawCode raw_code, uint32_t reserve) {
std::vector<RawCode> codes;
// absl::flat_hash_map<uint64_t, uint64_t> cases; // <code, mask>

52
src/core/main.cc

@ -46,38 +46,38 @@ 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) {
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) {
FastCal_demo(code);
break;
}
coff += 0.01;
}
std::cout << std::endl;
}
}
// 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;

Loading…
Cancel
Save