18 template <
typename RandomGenerator = std::default_random_engine>
21 RandomGenerator& = RandomGenerator())
28 template <
typename... LabelSet,
29 typename RandomGenerator = std::default_random_engine>
30 typename tupleset<LabelSet...>::value_t
32 RandomGenerator& gen = RandomGenerator())
39 template <
typename... LabelSet,
41 typename RandomGenerator = std::default_random_engine>
42 typename tupleset<LabelSet...>::value_t
49 return ls.tuple(
random_label(ls.template set<I>(), gen)...);
54 template <
typename GenSet,
55 typename RandomGenerator = std::default_random_engine>
56 typename wordset<GenSet>::value_t
58 RandomGenerator& gen = RandomGenerator())
61 "random_label: the alphabet needs at least 1 letter");
62 auto dis = std::uniform_int_distribution<>(0, 5);
63 auto res_label = ls.
one();
65 for (
auto i = 0; i < dis(gen); ++i)
72 template <
typename LabelSet,
73 typename RandomGenerator = std::default_random_engine>
74 typename LabelSet::value_t
76 RandomGenerator& gen = RandomGenerator())
78 require(!ls.generators().empty(),
79 "random_label: the alphabet needs at least 1 letter");
82 return ls.value(pick(ls.generators()));
87 template <
typename LabelSet,
88 typename RandomGenerator = std::default_random_engine>
89 typename nullableset<LabelSet>::value_t
91 RandomGenerator& gen = RandomGenerator())
94 auto dis = std::bernoulli_distribution(0.5);
103 template <
typename Context,
104 typename RandomGenerator = std::default_random_engine>
105 typename expressionset<Context>::value_t
107 RandomGenerator& gen = RandomGenerator())
116 template <
typename Ctx>
117 mutable_automaton<Ctx>
119 unsigned num_states,
float density = 0.1,
120 unsigned num_initial = 1,
unsigned num_final = 1,
121 float loop_chance = 0.0)
123 require(0 <= density && density <= 1,
124 "random: density must be in [0,1]");
125 require(0 <= loop_chance && loop_chance <= 1,
126 "random: loop chance must be in [0,1]");
129 automaton_t res = make_shared_ptr<automaton_t>(
ctx);
132 std::random_device rd;
134 if (getenv(
"VCSN_SEED"))
135 seed = std::mt19937::default_seed;
136 std::mt19937 gen(seed);
138 std::vector<state_t> states;
139 states.reserve(num_states);
141 std::vector<int> state_randomizer;
142 state_randomizer.reserve(num_states);
147 using state_set = std::set<int>;
150 state_set unreachables;
152 for (
unsigned i = 0; i < num_states; ++i)
154 states.push_back(res->new_state());
155 state_randomizer.push_back(i);
158 unreachables.emplace(i);
160 res->set_initial(states[i]);
165 for (
unsigned i = 0; i < num_final; ++i)
167 auto dis = std::uniform_int_distribution<>(i, num_states - 1);
168 int index = dis(gen);
169 res->set_final(states[state_randomizer[index]]);
172 std::swap(state_randomizer[index], state_randomizer[i]);
178 auto bin = std::binomial_distribution<>(num_states - 1, density);
183 while (!worklist.empty())
185 auto src = states[*worklist.begin()];
186 worklist.erase(worklist.begin());
190 unsigned nsucc = 1 + bin(gen);
195 bool saw_unreachable =
false;
196 auto possibilities = num_states;
205 && !unreachables.empty())
208 dst = pick.pop(unreachables);
209 worklist.insert(dst);
215 = std::uniform_int_distribution<>(0, possibilities - 1);
216 int index = dis(gen);
219 dst = state_randomizer[index];
223 std::swap(state_randomizer[index],
224 state_randomizer[possibilities]);
226 state_set::iterator j = unreachables.find(dst);
227 if (j != unreachables.end())
229 worklist.insert(dst);
230 unreachables.erase(j);
231 saw_unreachable =
true;
234 res->add_transition(src, states[dst],
243 auto dis = std::bernoulli_distribution(0.5);
244 for (
auto s : res->states())
246 res->add_transition(s, s,
random_label(*ctx.labelset(), gen));
257 template <
typename Ctx,
typename,
typename,
typename,
typename,
typename>
260 unsigned num_states,
float density,
261 unsigned num_initial,
unsigned num_final,
264 const auto& c = ctx->as<Ctx>();
266 num_initial, num_final,
277 template <
typename Ctx>
278 mutable_automaton<Ctx>
281 require(0 < num_states,
"num_states must be > 0");
285 automaton_t res = make_shared_ptr<automaton_t>(
ctx);
287 std::random_device rd;
289 if (getenv(
"VCSN_SEED"))
290 seed = std::mt19937::default_seed;
291 auto gen = std::mt19937(seed);
292 auto dis = std::uniform_int_distribution<int>(0, num_states - 1);
294 auto states = std::vector<state_t>{};
295 states.reserve(num_states);
297 for (
unsigned i = 0; i < num_states; ++i)
298 states.push_back(res->new_state());
300 for (
unsigned i = 0; i < num_states; ++i)
301 for (
auto l : ctx.labelset()->generators())
302 res->add_transition(states[i], states[dis(gen)], l,
303 ctx.weightset()->one());
305 res->set_initial(states[dis(gen)]);
306 res->set_final(states[dis(gen)]);
316 template <
typename Ctx,
typename>
320 const auto& c = ctx->as<Ctx>();
value_t value(Args &&...args) const
Value constructor.
Implementation of labels are words.
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
Implementation of labels are nullables (letter or empty).
genset_t generators() const
The generators. Meaningful for labelsets only.
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
const genset_t & generators() const
value_t value(Args &&...args) const
weightset_mixin< detail::tupleset_impl< LabelSets... >> tupleset
Provide a variadic mul on top of a binary mul(), and one().
automaton random_automaton_deterministic(const context &ctx, unsigned num_states)
Bridge.
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
random_selector< RandomGenerator > make_random_selector(RandomGenerator &g)
std::shared_ptr< const detail::context_base > context
A dyn::context.
oneset::value_t random_label(const oneset &ls, RandomGenerator &=RandomGenerator())
Random label from oneset.
auto mul(Args &&...args) const -> decltype(this->genset() -> mul(std::forward< Args >(args)...))
std::shared_ptr< detail::automaton_base > automaton
static ATTRIBUTE_PURE constexpr value_t one()
mutable_automaton< Ctx > random_automaton_deterministic(const Ctx &ctx, unsigned num_states)
static dyn::context ctx(const driver &d)
Get the context of the driver.
Implementation of labels are ones: there is a single instance of label.
tupleset< LabelSet... >::value_t random_label_(const tupleset< LabelSet... > &ls, RandomGenerator &gen, detail::index_sequence< I... >)
Implementation detail for random label from tupleset.
const labelset_ptr labelset() const
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)
automaton random_automaton(const context &ctx, unsigned num_states, float density, unsigned num_initial, unsigned num_final, float loop_chance)
Bridge.