00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_TOOLS_GEN_RANDOM_HXX
00018 # define VCSN_TOOLS_GEN_RANDOM_HXX
00019
00020 # include <vaucanson/tools/gen_random.hh>
00021 # include <vaucanson/misc/usual_macros.hh>
00022
00023 # include <cstdlib>
00024
00025 namespace vcsn {
00026 namespace tools {
00027
00028 using namespace algebra;
00029
00030
00031
00032
00033
00034 template <class AutoSet>
00035 AutoSet
00036 GenRandomAutomataSet::generate(SELECTOR(AutomataBase<AutoSet>),
00037 unsigned nb_letter)
00038 {
00039
00040 AUTOMATA_SET_TYPES(AutoSet);
00041
00042 alphabet_t alpha;
00043 unsigned nb = alea(nb_letter ? nb_letter :
00044 alpha.max_size());
00045 for (unsigned i = 0; i < nb; ++i)
00046 alpha.insert(alpha.random_letter());
00047
00048 monoid_t monoid(alpha);
00049 semiring_t semi;
00050 series_set_t series(semi, monoid);
00051 automata_set_t autoset(series);
00052 return autoset;
00053 }
00054
00055 template <class AutoSet>
00056 AutoSet
00057 GenRandomAutomataSet::generate(SELECTOR(TransducerBase<AutoSet>),
00058 unsigned input_nb_letter,
00059 unsigned output_nb_letter)
00060 {
00061 AUTOMATA_SET_TYPES(AutoSet);
00062
00063 alphabet_t input_alpha;
00064 alphabet_t output_alpha;
00065
00066 unsigned nb = alea(input_nb_letter ? input_nb_letter :
00067 input_alpha.max_size());
00068 for (unsigned i = 0; i < nb; ++i)
00069 input_alpha.insert(input_alpha.random_letter());
00070
00071 nb = alea(output_nb_letter ? output_nb_letter :
00072 output_alpha.max_size());
00073 for (unsigned i = 0; i < nb; ++i)
00074 output_alpha.insert(output_alpha.random_letter());
00075
00076 monoid_t input_monoid(input_alpha);
00077 monoid_t output_monoid(output_alpha);
00078
00079 typename semiring_t::semiring_t semi;
00080 semiring_t output_series(semi, output_monoid);
00081
00082 series_set_t series(output_series, input_monoid);
00083
00084 automata_set_t auto_set(series);
00085 return auto_set;
00086 }
00087
00088 unsigned alea(unsigned max)
00089 {
00090 return int (1 + float (max) * rand() / (RAND_MAX + 1.0));
00091 }
00092
00093
00094
00095
00096
00097 template <class TAutomata, class AutomataSetGenerator>
00098 GenRandomAutomata<TAutomata, AutomataSetGenerator>::GenRandomAutomata()
00099 {}
00100
00101
00102
00103
00104
00105
00106 template <class TAutomata, class AutomataSetGenerator>
00107 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00108 empty(unsigned nb_letter)
00109 {
00110 automata_set_t aset =
00111 GenRandomAutomataSet::generate(SELECT(automata_set_t), nb_letter);
00112 TAutomata work(aset);
00113 return work;
00114 }
00115
00116 template <class TAutomata, class AutomataSetGenerator>
00117 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00118 empty(const automata_set_t& set)
00119 {
00120 TAutomata work(set);
00121 return work;
00122 }
00123
00124
00125
00126
00127
00128 template <class TAutomata, class AutomataSetGenerator>
00129 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00130 generate(unsigned nb_state, unsigned nb_transition_,
00131 unsigned istate, unsigned fstate,
00132 unsigned nb_letter)
00133 {
00134 automata_set_t aset =
00135 GenRandomAutomataSet::generate(SELECT(automata_set_t), nb_letter);
00136 return generate(aset, nb_state, nb_transition_, istate, fstate);
00137 }
00138
00139 template <class TAutomata, class AutomataSetGenerator>
00140 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00141 generate(const automata_set_t& set,
00142 unsigned nb_state, unsigned nb_transition_,
00143 unsigned istate, unsigned fstate)
00144 {
00145 AUTOMATON_TYPES(TAutomata);
00146 AUTOMATON_FREEMONOID_TYPES(TAutomata);
00147 int nb_transition = nb_transition_;
00148
00149 if (nb_transition_ < nb_state - 1)
00150 nb_transition = nb_state - 1;
00151 if (fstate > nb_state) fstate = nb_state;
00152 if (fstate <= 0) fstate = 1;
00153 if (istate > nb_state) istate = nb_state;
00154 if (istate <= 0) istate = 1;
00155
00156 TAutomata work(set);
00157
00158 for (unsigned i = 0; i < nb_state; i++)
00159 work.add_state();
00160
00161
00162 state_iterator prev = work.states().begin();
00163 state_iterator i = prev;
00164 ++i;
00165 for (; i != work.states().end(); ++i)
00166 {
00167 nb_transition--;
00168 std::set<htransition_t> dst;
00169 letter_t e = set.series().monoid().alphabet().choose();
00170 work.letter_deltac(dst, *prev, e, delta_kind::transitions());
00171 if (dst.size() == 0)
00172 work.add_letter_transition(*prev, *i, e);
00173 prev = i;
00174 }
00175
00176 for (int i = 0; i < nb_transition; i++)
00177 {
00178 std::set<hstate_t> dst;
00179 letter_t e = set.series().monoid().alphabet().choose();
00180 hstate_t s = work.choose_state();
00181 hstate_t a = work.choose_state();
00182 work.letter_deltac(dst, s, e, delta_kind::states());
00183 if (dst.find(a) == dst.end())
00184 work.add_letter_transition(s, a, e);
00185 }
00186
00187 work.set_initial(*work.states().begin());
00188
00189 for (unsigned i = 1; i < istate; i++)
00190 {
00191 hstate_t tmp = work.choose_state();
00192 while (work.is_initial(tmp))
00193 tmp = work.choose_state();
00194 work.set_initial(tmp);
00195 }
00196
00197 work.set_final(*--work.states().end());
00198
00199 for (unsigned i = 1; i < fstate; i++)
00200 {
00201 hstate_t tmp = work.choose_state();
00202 while (work.is_final(tmp))
00203 tmp = work.choose_state();
00204 work.set_final(tmp);
00205 }
00206
00207 return work;
00208 }
00209
00210
00211
00212
00213
00214 template <class TAutomata, class AutomataSetGenerator>
00215 unsigned GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00216 nb_transition_circle(TAutomata work, hstate_t state)
00217 {
00218 AUTOMATON_TYPES(TAutomata);
00219 unsigned res = 0;
00220
00221 for_all_transitions(i, work)
00222 if ((work.src_of(*i) == state) && (work.dst_of(*i) == state))
00223 res++;
00224
00225 return res;
00226 }
00227
00228 template <class TAutomata, class AutomataSetGenerator>
00229 void GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00230 del_transition_circle(TAutomata& work, hstate_t state)
00231 {
00232 AUTOMATON_TYPES(TAutomata);
00233
00234 std::list<htransition_t> to_remove;
00235 for_all_transitions(i, work)
00236 {
00237 if ((work.src_of(*i) == state) && (work.dst_of(*i) == state))
00238 to_remove.push_back(*i);
00239 }
00240 for_all_const_(std::list<htransition_t>, e, to_remove)
00241 work.del_transition(*e);
00242 }
00243
00244
00245
00246
00247
00248
00249 template <class TAutomata, class AutomataSetGenerator>
00250 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00251 generate_with_epsilon(unsigned nb_state,
00252 unsigned nb_transition,
00253 unsigned nb_epsilon_min,
00254 unsigned nb_epsilon_max)
00255 {
00256 automata_set_t aset =
00257 GenRandomAutomataSet::generate(SELECT(automata_set_t));
00258 TAutomata a = generate_with_epsilon(aset, nb_state, nb_transition,
00259 nb_epsilon_min, nb_epsilon_max);
00260 return a;
00261 }
00262
00263
00264
00265 template <class TAutomata, class AutomataSetGenerator>
00266 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00267 generate_with_epsilon(const automata_set_t& set,
00268 unsigned nb_state,
00269 unsigned nb_transition,
00270 unsigned nb_epsilon_min,
00271 unsigned nb_epsilon_max)
00272 {
00273 TAutomata a = generate(set, nb_state, nb_transition);
00274 unsigned nb_eps = nb_epsilon_min + alea(nb_epsilon_max - nb_epsilon_min);
00275
00276 for (unsigned i = 0; i < nb_eps; ++i)
00277 {
00278 hstate_t f = a.choose_state();
00279 hstate_t t = a.choose_state();
00280 a.add_spontaneous(f, t);
00281 }
00282 return a;
00283 }
00284
00285
00286
00287
00288
00289
00290 template <class TAutomata, class AutomataSetGenerator>
00291 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00292 generate_dfa(unsigned nb_state,
00293 unsigned size_alphabet,
00294 unsigned fstate)
00295 {
00296 automata_set_t aset =
00297 GenRandomAutomataSet::generate(SELECT(automata_set_t), size_alphabet);
00298 TAutomata a = generate_dfa(aset, nb_state, fstate);
00299 return a;
00300 }
00301
00302
00303
00304 template <class TAutomata, class AutomataSetGenerator>
00305 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00306 generate_dfa(const automata_set_t& set,
00307 unsigned nb_state,
00308 unsigned fstate)
00309 {
00310 AUTOMATON_TYPES(TAutomata);
00311 AUTOMATON_FREEMONOID_TYPES(TAutomata);
00312 automaton_t work(set);
00313
00314 for (unsigned i = 0; i < nb_state; i++)
00315 work.add_state();
00316
00317 for_all_states(i, work)
00318 {
00319 for_all_letters(j, set.series().monoid().alphabet())
00320 work.add_letter_transition(*i,work.choose_state(),*j);
00321 while (nb_transition_circle(work, *i) == set.series().monoid().alphabet().size())
00322 {
00323 del_transition_circle(work, *i);
00324 for_all_letters(j, set.series().monoid().alphabet())
00325 {
00326 std::set<hstate_t> ret;
00327 work.letter_deltac(ret, *i, *j, delta_kind::states());
00328 if (ret.size() == 0)
00329 {
00330 hstate_t s;
00331 while ((s = work.choose_state()) == *i);
00332 work.add_letter_transition(*i, s, *j);
00333 }
00334 }
00335 }
00336 }
00337
00338
00339 work.set_initial(work.choose_state());
00340
00341
00342 for (unsigned i = 0; i < fstate; i++)
00343 {
00344 hstate_t tmp = work.choose_state();
00345 while (work.is_final(tmp))
00346 tmp = work.choose_state();
00347 work.set_final(tmp);
00348 }
00349 return work;
00350 }
00351
00352
00353
00354
00355
00356
00357 template <class TAutomata, class AutomataSetGenerator>
00358 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00359 generate_normalized(unsigned nb_state, unsigned density)
00360 {
00361 automata_set_t aset =
00362 AutomataSetGenerator::generate(SELECT(automata_set_t));
00363 TAutomata a = generate_normalized(aset, nb_state, density);
00364 return a;
00365 }
00366
00367 template <class TAutomata, class AutomataSetGenerator>
00368 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00369 generate_normalized(const automata_set_t& set,
00370 unsigned nb_state,
00371 unsigned density)
00372 {
00373 typedef typename TAutomata::state_iterator state_iterator;
00374 typedef typename TAutomata::monoid_t::alphabets_elt_t alphabets_elt_t;
00375
00376 if (density == 0)
00377 density = 1;
00378
00379 TAutomata work = generate(set, nb_state,
00380 nb_state + alea(nb_state * density));
00381
00382 for (state_iterator i = work.states().begin(); i != work.states().end();
00383 i++)
00384 {
00385 if (work.is_initial(*i))
00386 work.unset_initial(*i);
00387 if (work.is_final(*i))
00388 work.unset_final(*i);
00389 }
00390
00391 hstate_t init = work.add_state();
00392 hstate_t final = work.add_state();
00393
00394 work.set_initial(init);
00395 work.set_final(final);
00396
00397 const alphabets_elt_t&
00398 alpha = work.structure().series().monoid().alphabet();
00399
00400 hstate_t tmp;
00401
00402 for (unsigned i = 0; i < density; i++)
00403 if (tmp = work.choose_state() != init)
00404 work.add_letter_transition(init, tmp,
00405 alpha.choose());
00406
00407 for (unsigned i =0; i < density; i++)
00408 if (tmp = work.choose_state() != final)
00409 work.add_letter_transition(tmp, final,
00410 alpha.choose());
00411
00412 return work;
00413 }
00414
00415 }
00416 }
00417
00418 #endif // ! VCSN_TOOLS_GEN_RANDOM_HXX