17 template <
typename RandomGenerator = std::default_random_engine>
20 RandomGenerator& = RandomGenerator())
25 template <
typename... LabelSet,
26 typename RandomGenerator = std::default_random_engine>
27 typename tupleset<LabelSet...>::value_t
29 RandomGenerator& gen = RandomGenerator())
34 template <
typename... LabelSet,
36 typename RandomGenerator = std::default_random_engine>
37 typename tupleset<LabelSet...>::value_t
42 return ls.value(std::make_tuple(
random_label(ls.template set<I>(), gen)...));
45 template <
typename GenSet,
46 typename RandomGenerator = std::default_random_engine>
47 typename wordset<GenSet>::value_t
49 RandomGenerator& gen = RandomGenerator())
51 std::uniform_int_distribution<> dis(0, 5);
52 auto res_label = ls.
one();
54 for (
auto i = 0; i < dis(gen); ++i)
59 template <
typename LabelSet,
60 typename RandomGenerator = std::default_random_engine>
61 typename LabelSet::value_t
63 RandomGenerator& gen = RandomGenerator())
67 return ls.value(pick(ls.genset()));
70 template <
typename LabelSet,
71 typename RandomGenerator = std::default_random_engine>
72 typename nullableset<LabelSet>::value_t
74 RandomGenerator& gen = RandomGenerator())
76 std::bernoulli_distribution dis(0.5);
84 template <
typename Context,
85 typename RandomGenerator = std::default_random_engine>
86 typename expressionset<Context>::value_t
88 RandomGenerator& gen = RandomGenerator())
97 template <
typename Ctx>
98 mutable_automaton<Ctx>
100 unsigned num_states,
float density = 0.1,
101 unsigned num_initial = 1,
unsigned num_final = 1,
102 float loop_chance = 0.0)
104 require(0 <= density && density <= 1,
105 "random: density must be in [0,1]");
106 require(0 <= loop_chance && loop_chance <= 1,
107 "random: loop chance must be in [0,1]");
110 automaton_t res = make_shared_ptr<automaton_t>(
ctx);
113 std::random_device rd;
115 if (getenv(
"VCSN_SEED"))
116 seed = std::mt19937::default_seed;
117 std::mt19937 gen(seed);
119 std::vector<state_t> states;
120 states.reserve(num_states);
122 std::vector<int> state_randomizer;
123 state_randomizer.reserve(num_states);
128 using state_set = std::set<int>;
131 state_set unreachables;
133 for (
unsigned i = 0; i < num_states; ++i)
135 states.push_back(res->new_state());
136 state_randomizer.push_back(i);
139 unreachables.emplace(i);
141 res->set_initial(states[i]);
146 for (
unsigned i = 0; i < num_final; ++i)
148 std::uniform_int_distribution<> dis(i, num_states - 1);
149 int index = dis(gen);
150 res->set_final(states[state_randomizer[index]]);
153 std::swap(state_randomizer[index], state_randomizer[i]);
159 std::binomial_distribution<> bin(num_states - 1, density);
164 while (!worklist.empty())
166 auto src = states[*worklist.begin()];
167 worklist.erase(worklist.begin());
171 unsigned nsucc = 1 + bin(gen);
176 bool saw_unreachable =
false;
177 auto possibilities = num_states;
186 && !unreachables.empty())
189 dst = pick.
pop(unreachables);
190 worklist.insert(dst);
195 std::uniform_int_distribution<> dis(0, possibilities - 1);
196 int index = dis(gen);
199 dst = state_randomizer[index];
203 std::swap(state_randomizer[index],
204 state_randomizer[possibilities]);
206 state_set::iterator j = unreachables.find(dst);
207 if (j != unreachables.end())
209 worklist.insert(dst);
210 unreachables.erase(j);
211 saw_unreachable =
true;
214 res->add_transition(src, states[dst],
223 std::bernoulli_distribution bern(0.5);
224 for (
auto s : res->states())
226 res->add_transition(s, s,
random_label(*ctx.labelset(), gen));
237 template <
typename Ctx,
typename,
typename,
typename,
typename,
typename>
240 unsigned num_states,
float density,
241 unsigned num_initial,
unsigned num_final,
244 const auto& c = ctx->as<Ctx>();
246 num_initial, num_final,
257 template <
typename Ctx>
258 mutable_automaton<Ctx>
261 require(0 < num_states,
"num_states must be > 0");
265 automaton_t res = make_shared_ptr<automaton_t>(
ctx);
267 std::random_device rd;
269 if (getenv(
"VCSN_SEED"))
270 seed = std::mt19937::default_seed;
271 std::mt19937 gen(seed);
272 std::uniform_int_distribution<int> distrib(0, num_states - 1);
274 std::vector<state_t> states;
275 states.reserve(num_states);
277 for (
unsigned i = 0; i < num_states; ++i)
278 states.push_back(res->new_state());
280 for (
unsigned i = 0; i < num_states; ++i)
281 for (
auto l : ctx.labelset()->genset())
282 res->add_transition(states[i], states[distrib(gen)], l,
283 ctx.weightset()->one());
285 res->set_initial(states[distrib(gen)]);
286 res->set_final(states[distrib(gen)]);
296 template <
typename Ctx,
typename>
300 const auto& c = ctx->as<Ctx>();
struct random_selector< RandomGenerator > make_random_selector(const RandomGenerator &g) ATTRIBUTE_PURE
std::shared_ptr< const detail::context_base > context
A dyn::context.
mutable_automaton< Ctx > random_automaton(const Ctx &ctx, unsigned num_states, float density=0.1, unsigned num_initial=1, unsigned num_final=1, float loop_chance=0.0)
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
value_t value(Args &&...args) const
mutable_automaton< Ctx > random_automaton_deterministic(const Ctx &ctx, unsigned num_states)
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
value_t value(Args &&...args) const
Value constructor.
static dyn::context ctx(const driver &d)
Get the context of the driver.
const genset_t & genset() const
Provide a variadic mul on top of a binary mul(), and one().
Implementation of labels are ones: there is a single instance of label.
std::shared_ptr< detail::automaton_base > automaton
static ATTRIBUTE_PURE constexpr value_t one()
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message.
auto pop(Container &c) -> typename Container::value_type
A randomly selected member of c. Remove it from c.
const labelset_ptr labelset() const
automaton random_automaton(const context &ctx, unsigned num_states, float density, unsigned num_initial, unsigned num_final, float loop_chance)
Bridge.
automaton random_automaton_deterministic(const context &ctx, unsigned num_states)
Bridge.
weightset_mixin< detail::tupleset_impl< LabelSets...>> tupleset
oneset::value_t random_label(const oneset &ls, RandomGenerator &=RandomGenerator())
auto mul(Args &&...args) const -> decltype(this->genset().mul(std::forward< Args >(args)...))
Implementation of labels are words.
Implementation of labels are nullables (letter or empty).
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton