diff --git a/lib/test_suite.cpp b/lib/test_suite.cpp index a77a5ef..b74521f 100644 --- a/lib/test_suite.cpp +++ b/lib/test_suite.cpp @@ -41,7 +41,7 @@ void randomized_test(const mealy & specification, const transfer_sequences & pre // https://en.wikipedia.org/wiki/Geometric_distribution we have the random variable Y here uniform_int_distribution<> unfair_coin(0, rnd_length); - uniform_int_distribution prefix_selection(0, prefixes.size() - 1); + uniform_int_distribution prefix_selection(0, prefixes.size() - 1); uniform_int_distribution suffix_selection; uniform_int_distribution input_selection(0, specification.input_size - 1); diff --git a/lib/transfer_sequences.cpp b/lib/transfer_sequences.cpp index a459be7..25da8d8 100644 --- a/lib/transfer_sequences.cpp +++ b/lib/transfer_sequences.cpp @@ -6,66 +6,38 @@ #include #include #include +#include using namespace std; -transfer_sequences create_transfer_sequences(const mealy& machine, state s){ - vector visited(machine.graph_size, false); - vector words(machine.graph_size); - - priority_queue> work; - work.push({0, s}); - while(!work.empty()){ - const auto p = work.top(); - const auto u = p.second; - const auto d = p.first - 1; - work.pop(); - - if(visited[u]) continue; - - visited[u] = true; - - for(input i = 0; i < machine.input_size; ++i){ - const auto v = apply(machine, u, i).to; - if(visited[v]) continue; - - words[v] = words[u]; - words[v].push_back(i); - work.push({d, v}); - } - } - - return words; -} - -transfer_sequences create_randomized_transfer_sequences(const mealy & machine, state s, uint_fast32_t random_seed){ +transfer_sequences create_transfer_sequences(transfer_options const & opt, const mealy & machine, + state s, uint_fast32_t random_seed) { mt19937 generator(random_seed); - vector visited(machine.graph_size, false); + vector added(machine.graph_size, false); vector words(machine.graph_size); vector all_inputs(machine.input_size); iota(begin(all_inputs), end(all_inputs), input(0)); - priority_queue> work; - work.push({0, s}); - while(!work.empty()){ - const auto p = work.top(); - const auto u = p.second; - const auto d = p.first - 1; + // state + queue work; + work.push(s); + added[s] = true; + while (!work.empty()) { + const auto u = work.front(); work.pop(); - if(visited[u]) continue; - - visited[u] = true; - - shuffle(begin(all_inputs), end(all_inputs), generator); - for(input i : all_inputs){ + // NOTE: we could also shuffle work, but we would need to do this per distance + // the current shuffle is an approximation of real randomization, but easier to implement. + if (opt.randomized) shuffle(begin(all_inputs), end(all_inputs), generator); + for (input i : all_inputs) { const auto v = apply(machine, u, i).to; - if(visited[v]) continue; + if (added[v]) continue; + work.push(v); + added[v] = true; words[v] = words[u]; words[v].push_back(i); - work.push({d, v}); } } diff --git a/lib/transfer_sequences.hpp b/lib/transfer_sequences.hpp index 40bf7f6..285efa3 100644 --- a/lib/transfer_sequences.hpp +++ b/lib/transfer_sequences.hpp @@ -4,7 +4,15 @@ struct mealy; +// state -> sequence going to that state using transfer_sequences = std::vector; -transfer_sequences create_transfer_sequences(mealy const & machine, state s); -transfer_sequences create_randomized_transfer_sequences(mealy const & machine, state s, uint_fast32_t random_seed); +struct transfer_options { + bool randomized; +}; + +const transfer_options randomized_transfer_sequences{true}; +const transfer_options canonical_transfer_sequences{false}; + +transfer_sequences create_transfer_sequences(transfer_options const & opt, mealy const & machine, + state s, uint_fast32_t random_seed); diff --git a/src/main.cpp b/src/main.cpp index 7640400..07364fb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -125,13 +125,11 @@ int main(int argc, char *argv[]) try { return sequence_; }(); - auto transfer_sequences = [&]{ + auto transfer_sequences = [&] { time_logger t("determining transfer sequences"); - if(randomize_prefixes){ - return create_randomized_transfer_sequences(machine, 0, random_seeds[2]); - } else { - return create_transfer_sequences(machine, 0); - } + return create_transfer_sequences(randomize_prefixes ? randomized_transfer_sequences + : canonical_transfer_sequences, + machine, 0, random_seeds[2]); }(); auto inputs = create_reverse_map(translation.input_indices); diff --git a/src/pre_gephi_tool.cpp b/src/pre_gephi_tool.cpp index d8f46b6..d1e99e5 100644 --- a/src/pre_gephi_tool.cpp +++ b/src/pre_gephi_tool.cpp @@ -47,7 +47,7 @@ int main(int argc, char *argv[]){ vector> visited(machine.graph_size); for(size_t i = 0; i <= maximal_hypothesis; ++i){ clog << "Visiting hypo " << i << endl; - const auto state_cover = create_transfer_sequences(hypotheses[i], 0); + const auto state_cover = create_transfer_sequences(canonical_transfer_sequences, hypotheses[i], 0, 0); for(auto && p : state_cover){ state s = 0; for(auto && inp : p){ diff --git a/src/stats.cpp b/src/stats.cpp index c919386..3289334 100644 --- a/src/stats.cpp +++ b/src/stats.cpp @@ -74,7 +74,7 @@ static void print_stats_for_machine(string filename) { const auto reachable_machine = reachable_submachine(machine, 0); cout << '\t' << reachable_machine.graph_size << " reachable states" << endl; - const auto prefixes = create_transfer_sequences(reachable_machine, 0); + const auto prefixes = create_transfer_sequences(canonical_transfer_sequences, reachable_machine, 0, 0); cout << "prefixes "; print_quantiles(prefixes, [](auto const & l) { return l.size(); }, cout); cout << endl;