1 #ifndef VCSN_ALGOS_RANDOM_HH
2 # define VCSN_ALGOS_RANDOM_HH
18 template <
typename RandomGenerator = std::default_random_engine>
21 RandomGenerator& = RandomGenerator())
27 typename RandomGenerator = std::default_random_engine>
28 typename tupleset<
LabelSet...>::value_t
30 RandomGenerator& gen = RandomGenerator())
37 typename RandomGenerator = std::default_random_engine>
38 typename tupleset<
LabelSet...>::value_t
48 typename RandomGenerator = std::default_random_engine>
49 typename LabelSet::value_t
51 RandomGenerator& gen = RandomGenerator())
55 return ls.value(pick(ls.genset()));
59 typename RandomGenerator = std::default_random_engine>
60 typename nullableset<LabelSet>::value_t
62 RandomGenerator& gen = RandomGenerator())
64 std::uniform_int_distribution<> dis(0, 1);
71 template <
typename Context,
72 typename RandomGenerator = std::default_random_engine>
73 typename ratexpset<Context>::value_t
75 RandomGenerator& gen = RandomGenerator())
84 template <
typename Ctx>
85 mutable_automaton<Ctx>
87 unsigned num_states,
float density = 0.1,
88 unsigned num_initial = 1,
unsigned num_final = 1)
90 require(0 <= density && density <= 1,
91 "random: density must be in [0,1]");
94 automaton_t res = make_shared_ptr<automaton_t>(ctx);
97 std::random_device rd;
99 if (getenv(
"VCSN_SEED"))
100 seed = std::mt19937::default_seed;
101 std::mt19937 gen(seed);
103 std::vector<state_t> states;
104 states.reserve(num_states);
106 std::vector<int> state_randomizer;
107 state_randomizer.reserve(num_states);
112 using state_set = std::set<int>;
115 state_set unreachables;
117 for (
unsigned i = 0; i < num_states; ++i)
119 states.push_back(res->new_state());
120 state_randomizer.push_back(i);
123 unreachables.emplace(i);
125 res->set_initial(states[i]);
130 for (
unsigned i = 0; i < num_final; ++i)
132 std::uniform_int_distribution<> dis(i, num_states - 1);
133 int index = dis(gen);
134 res->set_final(states[state_randomizer[index]]);
137 std::swap(state_randomizer[index], state_randomizer[i]);
143 std::binomial_distribution<> bin(num_states - 1, density);
148 while (!worklist.empty())
150 auto src = states[*worklist.begin()];
151 worklist.erase(worklist.begin());
155 unsigned nsucc = 1 + bin(gen);
160 bool saw_unreachable =
false;
161 auto possibilities = num_states;
170 && !unreachables.empty())
173 dst = pick.
pop(unreachables);
174 worklist.insert(dst);
179 std::uniform_int_distribution<> dis(0, possibilities - 1);
180 int index = dis(gen);
183 dst = state_randomizer[index];
187 std::swap(state_randomizer[index],
188 state_randomizer[possibilities]);
190 state_set::iterator j = unreachables.find(dst);
191 if (j != unreachables.end())
193 worklist.insert(dst);
194 unreachables.erase(j);
195 saw_unreachable =
true;
198 res->add_transition(src, states[dst],
202 return std::move(res);
210 template <
typename Ctx,
typename,
typename,
typename,
typename>
213 unsigned num_states,
float density,
214 unsigned num_initial = 1,
unsigned num_final = 1)
216 const auto& c = ctx->as<Ctx>();
218 num_initial, num_final));
223 unsigned n,
float density,
224 unsigned num_initial,
unsigned num_final) ->
automaton);
233 template <
typename Ctx>
234 mutable_automaton<Ctx>
237 require(0 < num_states,
"num_states must be > 0");
241 automaton_t res = make_shared_ptr<automaton_t>(ctx);
243 std::random_device rd;
245 if (getenv(
"VCSN_SEED"))
246 seed = std::mt19937::default_seed;
247 std::mt19937 gen(seed);
248 std::uniform_int_distribution<int> distrib(0, num_states - 1);
250 std::vector<state_t> states;
251 states.reserve(num_states);
253 for (
unsigned i = 0; i < num_states; ++i)
254 states.push_back(res->new_state());
256 for (
unsigned i = 0; i < num_states; ++i)
257 for (
auto l : ctx.labelset()->genset())
258 res->add_transition(states[i], states[distrib(gen)], l,
259 ctx.weightset()->one());
261 res->set_initial(states[distrib(gen)]);
262 res->set_final(states[distrib(gen)]);
272 template <
typename Ctx,
typename>
276 const auto& c = ctx->as<Ctx>();
288 #endif // !VCSN_ALGOS_RANDOM_HH
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
std::shared_ptr< detail::automaton_base > automaton
value_t value(const std::tuple< Args...> &args) const
Construct a value.
mutable_automaton< Ctx > random(const Ctx &ctx, unsigned num_states, float density=0.1, unsigned num_initial=1, unsigned num_final=1)
A ValueSet which is a Cartesian product of ValueSets.
static constexpr indices_t indices
automaton random(const context &ctx, unsigned num_states, float density, unsigned num_initial=1, unsigned num_final=1)
Bridge.
Implementation of labels are nullables (letter or empty).
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
Implementation of labels are ones: there is a single instance of label.
const labelset_ptr labelset() const
struct random_selector< RandomGenerator > make_random_selector(const RandomGenerator &g) ATTRIBUTE_PURE
mutable_automaton< Ctx > random_deterministic(const Ctx &ctx, unsigned num_states)
Provide a variadic mul on top of a binary mul(), and one().
oneset::value_t random_label(const oneset &ls, RandomGenerator &=RandomGenerator())
std::shared_ptr< const detail::context_base > context
auto pop(Container &c) -> typename Container::value_type
A randomly selected member of c. Remove it from c.
automaton random_deterministic(const context &ctx, unsigned num_states)
Bridge.
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
static ATTRIBUTE_PURE constexpr value_t one()
value_t value(Args &&...args) const
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message.