State saving + conditions optimization

This commit is contained in:
2020-03-29 21:01:58 +03:00
parent e99f1874ad
commit 3c0d408989

109
main.cpp
View File

@@ -16,6 +16,7 @@ typedef uint16_t Storage;
const size_t ARGS_COUNT = 4;
const size_t FUNCTION_LEN = 1ll << ARGS_COUNT;
const size_t FUNCTIONS_COUNT = 1ll << FUNCTION_LEN;
const bool ONLY_CREATE_CLASSES = true;
typedef Function<Storage, FUNCTION_LEN> MyFunction;
typedef BoolSquareMatrix<Storage, ARGS_COUNT> MyMatrix;
@@ -242,6 +243,51 @@ string preprocess_monom(string monom) {
return monom;
}
inline bool exists_test0 (const std::string& name) {
ifstream f(name.c_str());
return f.good();
}
string get_out_file_name(size_t rank_ind) {
return string("base_" + to_string(ARGS_COUNT) + "_rank_" + to_string(rank_ind) + ".txt");
}
size_t recover_ranks(vector< vector<MyFunction> >& ranks, vector<int8_t>& used_map, size_t& functions_remains) {
for (size_t rank_ind = 2; true; ++rank_ind) {
ifstream f_in(get_out_file_name(rank_ind).c_str(), std::ios::binary);
if ( not f_in.good() )
return rank_ind;
ranks.push_back(vector<MyFunction>());
while ( not f_in.eof() and f_in.good() ) {
char buf[sizeof(Storage)];
f_in.read(buf, sizeof(Storage));
Storage function_value = *reinterpret_cast<Storage*>(buf);
MyFunction f(function_value);
if (used_map.at(f.value()))
continue;
used_map.at(f.value()) = rank_ind;
--functions_remains;
ranks.back().push_back(f);
}
}
}
void save_rank(size_t rank_ind, vector<MyFunction>& rank_items) {
ofstream f_out(get_out_file_name(rank_ind).c_str(), ios::binary);
for (auto f: rank_items) {
Storage function_value = f.value();
f_out.write(reinterpret_cast<char*>(&function_value), sizeof(function_value));
}
}
void clean_trash_ranks(vector< vector<MyFunction> >& ranks) {
for (size_t rank_ind = 2; rank_ind < ranks.size() - 1; ++rank_ind)
ranks.at(rank_ind).clear();
}
void fill_ranks(vector<MyFunction> monomials) {
vector<int8_t> used_map(FUNCTIONS_COUNT, 0);
size_t functions_remains = FUNCTIONS_COUNT;
@@ -255,30 +301,61 @@ void fill_ranks(vector<MyFunction> monomials) {
--functions_remains;
used_map.at(el.value()) = 1;
}
size_t total_ranks = 1;
for (total_ranks = 1; functions_remains; ++total_ranks) {
ranks.push_back(vector<MyFunction>());
size_t total_ranks = recover_ranks(ranks, used_map, functions_remains);
clean_trash_ranks(ranks);
cout << "recovered to " << total_ranks << endl;
cout << "current ranks: " << endl;
for (auto&& r: ranks)
cout << r.size() << " ";
cout << endl;
for (; functions_remains; ++total_ranks) {
cout << "rank index = " << total_ranks << " remains: " << functions_remains << endl;
for (auto el_first: ranks.at(total_ranks - 1)) {
for (auto el_second: ranks.at(1)) {
vector<int8_t> temp_used_map(FUNCTIONS_COUNT, 0);
for (size_t ind_first = 0; ind_first != ranks[1].size(); ++ind_first) {
if ( ind_first % 20 == 0 ) {
for (auto&& r: ranks)
cout << r.size() << " ";
cout << endl;
cout << 100. * ind_first / ranks[1].size() << "% for " << ranks[1].size()
<< " x " << ranks.back().size() << endl;
}
const auto el_first = ranks[1][ind_first];
for (auto el_second: ranks.back()) {
MyFunction res_el = el_first xor el_second;
if ( used_map[res_el.value()] == 0 ) {
--functions_remains;
function_formulas[res_el.value()] =
preprocess_monom(function_formulas[el_first.value()]) +
" + " + preprocess_monom(function_formulas[el_second.value()]);
used_map.at(res_el.value()) = total_ranks;
ranks.at(total_ranks).push_back(res_el);
if constexpr ( not ONLY_CREATE_CLASSES ) {
if ( used_map[res_el.value()] == 0 ) {
function_formulas[res_el.value()] =
preprocess_monom(function_formulas[el_first.value()]) +
" + " + preprocess_monom(function_formulas[el_second.value()]);
}
}
temp_used_map[res_el.value()] = total_ranks;
}
}
if ( total_ranks - 1 > 1 )
ranks.at(total_ranks - 1).clear(); // больше не нужен
ranks.push_back(vector<MyFunction>());
clean_trash_ranks(ranks);
for (size_t func_ind = 0; func_ind < temp_used_map.size(); ++func_ind) {
if (not temp_used_map[func_ind] or used_map[func_ind] != 0)
continue;
--functions_remains;
auto cur_fn = MyFunction(func_ind);
auto val = cur_fn.value();
if (val >= used_map.size()) {
cout << val << " " << cur_fn.string() << endl;
continue;
}
used_map[val] = total_ranks;
ranks.back().push_back(cur_fn);
}
save_rank(total_ranks, ranks.back());
cout << "size for rank " << total_ranks << " is " << ranks.at(total_ranks).size() << endl;
}
if constexpr ( ONLY_CREATE_CLASSES ) {
return;
}
auto possible_tranformations = get_good_matrices();
cout << "Total " << possible_tranformations.size() << " linear tranformations" << endl;