mirror of
https://github.com/Jaxan/hybrid-ads.git
synced 2025-04-27 06:57:44 +02:00
Fixes bug in prefix sequences (sorry methods.cpp is still broken)
This commit is contained in:
parent
0d24dcf137
commit
e9ffbd3be8
6 changed files with 34 additions and 56 deletions
|
@ -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<size_t> prefix_selection(0, prefixes.size() - 1);
|
||||
uniform_int_distribution<state> prefix_selection(0, prefixes.size() - 1);
|
||||
uniform_int_distribution<size_t> suffix_selection;
|
||||
uniform_int_distribution<input> input_selection(0, specification.input_size - 1);
|
||||
|
||||
|
|
|
@ -6,66 +6,38 @@
|
|||
#include <numeric>
|
||||
#include <queue>
|
||||
#include <random>
|
||||
#include <tuple>
|
||||
|
||||
using namespace std;
|
||||
|
||||
transfer_sequences create_transfer_sequences(const mealy& machine, state s){
|
||||
vector<bool> visited(machine.graph_size, false);
|
||||
vector<word> words(machine.graph_size);
|
||||
|
||||
priority_queue<pair<int, state>> 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<bool> visited(machine.graph_size, false);
|
||||
vector<bool> added(machine.graph_size, false);
|
||||
vector<word> words(machine.graph_size);
|
||||
vector<input> all_inputs(machine.input_size);
|
||||
iota(begin(all_inputs), end(all_inputs), input(0));
|
||||
|
||||
priority_queue<pair<int, state>> 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<state> 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});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,15 @@
|
|||
|
||||
struct mealy;
|
||||
|
||||
// state -> sequence going to that state
|
||||
using transfer_sequences = std::vector<word>;
|
||||
|
||||
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);
|
||||
|
|
10
src/main.cpp
10
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);
|
||||
|
|
|
@ -47,7 +47,7 @@ int main(int argc, char *argv[]){
|
|||
vector<optional<size_t>> 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){
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue