Add generation methods to Markov
This commit is contained in:
parent
279f95b855
commit
87b239a53c
44
markov.hpp
44
markov.hpp
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <random>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -62,7 +63,37 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename IT, typename Generator>
|
||||||
|
T gen(IT iter, size_t size, Generator &g) const {
|
||||||
|
while (size > order()) {
|
||||||
|
iter++;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
return random_child(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gen_impl(iter, size, g, std::bool_constant<(ORDER > 0)>{});
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
template <typename IT, typename Generator>
|
||||||
|
T gen_impl(IT iter, size_t size, Generator &g,
|
||||||
|
std::bool_constant<true>) const {
|
||||||
|
auto child = children.find(*iter);
|
||||||
|
if (child == children.end()) {
|
||||||
|
return random_child(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
return child->second.gen(iter + 1, size - 1, g);
|
||||||
|
}
|
||||||
|
template <typename IT, typename Generator>
|
||||||
|
T gen_impl(IT iter, size_t size, Generator &g,
|
||||||
|
std::bool_constant<false>) const {
|
||||||
|
return random_child(g);
|
||||||
|
}
|
||||||
|
|
||||||
/* Finds the key or adds it */
|
/* Finds the key or adds it */
|
||||||
typename Children::iterator find(const T &key) {
|
typename Children::iterator find(const T &key) {
|
||||||
return children.try_emplace(key).first;
|
return children.try_emplace(key).first;
|
||||||
|
@ -104,6 +135,19 @@ public:
|
||||||
return 0.5 / double(total);
|
return 0.5 / double(total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Generator> T random_child(Generator &g) const {
|
||||||
|
std::uniform_int_distribution<size_t> dist(0u, total - 1);
|
||||||
|
auto val = dist(g);
|
||||||
|
for (auto &child : children) {
|
||||||
|
if (val < child.second.total) {
|
||||||
|
return child.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
val -= child.second.total;
|
||||||
|
}
|
||||||
|
return T{};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Leaf of the recursion with just a count */
|
/* Leaf of the recursion with just a count */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user