Sort & comment
This commit is contained in:
parent
87b239a53c
commit
de4b97f096
118
markov.hpp
118
markov.hpp
|
@ -63,60 +63,6 @@ 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:
|
|
||||||
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 */
|
|
||||||
typename Children::iterator find(const T &key) {
|
|
||||||
return children.try_emplace(key).first;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/* Probability of finding the first order() items (but at most size) in the
|
|
||||||
sequence */
|
|
||||||
template <typename IT> double probability(IT iter, size_t size) const {
|
|
||||||
if (size == 0) {
|
|
||||||
return 1.;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto child = children.find(*iter);
|
|
||||||
if (child != children.cend()) {
|
|
||||||
auto &val = child->second;
|
|
||||||
return (double(val.total) / double(total)) *
|
|
||||||
val.probability(iter + 1, size - 1);
|
|
||||||
} else {
|
|
||||||
return 0.5 / double(total);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Probability of finding the last item (but at most the order+1st) in the
|
/* Probability of finding the last item (but at most the order+1st) in the
|
||||||
model, given the previous sequence */
|
model, given the previous sequence */
|
||||||
template <typename IT> double final_probability(IT iter, size_t size) const {
|
template <typename IT> double final_probability(IT iter, size_t size) const {
|
||||||
|
@ -136,6 +82,40 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Generate one single item that can appear after the prefix given by iter and
|
||||||
|
size, using the RNG g */
|
||||||
|
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)>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Probability of finding the first order() items (but at most size) in the
|
||||||
|
sequence */
|
||||||
|
template <typename IT> double probability(IT iter, size_t size) const {
|
||||||
|
if (size == 0) {
|
||||||
|
return 1.;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto child = children.find(*iter);
|
||||||
|
if (child != children.cend()) {
|
||||||
|
auto &val = child->second;
|
||||||
|
return (double(val.total) / double(total)) *
|
||||||
|
val.probability(iter + 1, size - 1);
|
||||||
|
} else {
|
||||||
|
return 0.5 / double(total);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns a random item, weighted by the probability of child nodes */
|
||||||
template <typename Generator> T random_child(Generator &g) const {
|
template <typename Generator> T random_child(Generator &g) const {
|
||||||
std::uniform_int_distribution<size_t> dist(0u, total - 1);
|
std::uniform_int_distribution<size_t> dist(0u, total - 1);
|
||||||
auto val = dist(g);
|
auto val = dist(g);
|
||||||
|
@ -148,6 +128,31 @@ public:
|
||||||
}
|
}
|
||||||
return T{};
|
return T{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/* Finds the key or adds it */
|
||||||
|
typename Children::iterator find(const T &key) {
|
||||||
|
return children.try_emplace(key).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate an item for Markov chains of order 0 */
|
||||||
|
template <typename IT, typename Generator>
|
||||||
|
T gen_impl(IT iter, size_t size, Generator &g,
|
||||||
|
std::bool_constant<false>) const {
|
||||||
|
return random_child(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate an item for longer chains, using the prefix */
|
||||||
|
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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Leaf of the recursion with just a count */
|
/* Leaf of the recursion with just a count */
|
||||||
|
@ -159,15 +164,12 @@ public:
|
||||||
constexpr size_t order() const { return 0; }
|
constexpr size_t order() const { return 0; }
|
||||||
|
|
||||||
template <typename IT> void add(IT, size_t) { total++; }
|
template <typename IT> void add(IT, size_t) { total++; }
|
||||||
|
|
||||||
template <typename IT> bool dec(IT, size_t) {
|
template <typename IT> bool dec(IT, size_t) {
|
||||||
total--;
|
total--;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename IT> double probability(IT, size_t) const { return 1.; }
|
|
||||||
|
|
||||||
template <typename IT> double final_probability(IT, size_t) const {
|
template <typename IT> double final_probability(IT, size_t) const {
|
||||||
return 1.;
|
return 1.;
|
||||||
}
|
}
|
||||||
|
template <typename IT> double probability(IT, size_t) const { return 1.; }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user