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