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 std::set<htransition_t> dst;
00177 letter_t e = set.series().monoid().alphabet().choose();
00178 work.letter_deltac(dst, *prev, e, delta_kind::transitions());
00179 if (dst.size() == 0)
00180 work.add_letter_transition(*prev, *i, e);
00181 prev = i;
00182 }
00183
00184 for (int i = 0; i < nb_transition; i++)
00185 {
00186 std::set<hstate_t> dst;
00187 letter_t e = set.series().monoid().alphabet().choose();
00188 hstate_t s = work.choose_state();
00189 hstate_t a = work.choose_state();
00190 work.letter_deltac(dst, s, e, delta_kind::states());
00191 if (dst.find(a) == dst.end())
00192 work.add_letter_transition(s, a, e);
00193 }
00194
00195 work.set_initial(*work.states().begin());
00196
00197 for (unsigned i = 1; i < istate; i++)
00198 {
00199 hstate_t tmp = work.choose_state();
00200 while (work.is_initial(tmp))
00201 tmp = work.choose_state();
00202 work.set_initial(tmp);
00203 }
00204
00205 work.set_final(*--work.states().end());
00206
00207 for (unsigned i = 1; i < fstate; i++)
00208 {
00209 hstate_t tmp = work.choose_state();
00210 while (work.is_final(tmp))
00211 tmp = work.choose_state();
00212 work.set_final(tmp);
00213 }
00214
00215 return work;
00216 }
00217
00218
00219
00220
00221
00222 template <class TAutomata, class AutomataSetGenerator>
00223 unsigned GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00224 nb_transition_circle(TAutomata work, hstate_t state)
00225 {
00226 AUTOMATON_TYPES(TAutomata);
00227 unsigned res = 0;
00228
00229 for_all_transitions(i, work)
00230 if ((work.src_of(*i) == state) && (work.dst_of(*i) == state))
00231 res++;
00232
00233 return res;
00234 }
00235
00236 template <class TAutomata, class AutomataSetGenerator>
00237 void GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00238 del_transition_circle(TAutomata& work, hstate_t state)
00239 {
00240 AUTOMATON_TYPES(TAutomata);
00241
00242 std::list<htransition_t> to_remove;
00243 for_all_transitions(i, work)
00244 {
00245 if ((work.src_of(*i) == state) && (work.dst_of(*i) == state))
00246 to_remove.push_back(*i);
00247 }
00248 for_all_const_(std::list<htransition_t>, e, to_remove)
00249 work.del_transition(*e);
00250 }
00251
00252
00253
00254
00255
00256
00257 template <class TAutomata, class AutomataSetGenerator>
00258 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00259 generate_with_epsilon(unsigned nb_state,
00260 unsigned nb_transition,
00261 unsigned nb_epsilon_min,
00262 unsigned nb_epsilon_max)
00263 {
00264 automata_set_t aset =
00265 GenRandomAutomataSet::generate(SELECT(automata_set_t));
00266 TAutomata a = generate_with_epsilon(aset, nb_state, nb_transition,
00267 nb_epsilon_min, nb_epsilon_max);
00268 return a;
00269 }
00270
00271
00272
00273 template <class TAutomata, class AutomataSetGenerator>
00274 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00275 generate_with_epsilon(const automata_set_t& set,
00276 unsigned nb_state,
00277 unsigned nb_transition,
00278 unsigned nb_epsilon_min,
00279 unsigned nb_epsilon_max)
00280 {
00281 TAutomata a = generate(set, nb_state, nb_transition);
00282 unsigned nb_eps = nb_epsilon_min + alea(nb_epsilon_max - nb_epsilon_min);
00283
00284 for (unsigned i = 0; i < nb_eps; ++i)
00285 {
00286 hstate_t f = a.choose_state();
00287 hstate_t t = a.choose_state();
00288 a.add_spontaneous(f, t);
00289 }
00290 return a;
00291 }
00292
00293
00294
00295
00296
00297
00298 template <class TAutomata, class AutomataSetGenerator>
00299 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00300 generate_dfa(unsigned nb_state,
00301 unsigned size_alphabet,
00302 unsigned fstate)
00303 {
00304 automata_set_t aset =
00305 GenRandomAutomataSet::generate(SELECT(automata_set_t), size_alphabet);
00306 TAutomata a = generate_dfa(aset, nb_state, fstate);
00307 return a;
00308 }
00309
00310
00311
00312 template <class TAutomata, class AutomataSetGenerator>
00313 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00314 generate_dfa(const automata_set_t& set,
00315 unsigned nb_state,
00316 unsigned fstate)
00317 {
00318 AUTOMATON_TYPES(TAutomata);
00319 AUTOMATON_FREEMONOID_TYPES(TAutomata);
00320 automaton_t work(set);
00321
00322 for (unsigned i = 0; i < nb_state; i++)
00323 work.add_state();
00324
00325 for_all_states(i, work)
00326 {
00327 for_all_letters(j, set.series().monoid().alphabet())
00328 work.add_letter_transition(*i,work.choose_state(),*j);
00329 while (nb_transition_circle(work, *i) == set.series().monoid().alphabet().size())
00330 {
00331 del_transition_circle(work, *i);
00332 for_all_letters(j, set.series().monoid().alphabet())
00333 {
00334 std::set<hstate_t> ret;
00335 work.letter_deltac(ret, *i, *j, delta_kind::states());
00336 if (ret.size() == 0)
00337 {
00338 hstate_t s;
00339 while ((s = work.choose_state()) == *i) ;
00340 work.add_letter_transition(*i, s, *j);
00341 }
00342 }
00343 }
00344 }
00345
00346
00347 work.set_initial(work.choose_state());
00348
00349
00350 for (unsigned i = 0; i < fstate; i++)
00351 {
00352 hstate_t tmp = work.choose_state();
00353 while (work.is_final(tmp))
00354 tmp = work.choose_state();
00355 work.set_final(tmp);
00356 }
00357 return work;
00358 }
00359
00360
00361
00362
00363
00364
00365 template <class TAutomata, class AutomataSetGenerator>
00366 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00367 generate_normalized(unsigned nb_state, unsigned density)
00368 {
00369 automata_set_t aset =
00370 AutomataSetGenerator::generate(SELECT(automata_set_t));
00371 TAutomata a = generate_normalized(aset, nb_state, density);
00372 return a;
00373 }
00374
00375 template <class TAutomata, class AutomataSetGenerator>
00376 TAutomata GenRandomAutomata<TAutomata, AutomataSetGenerator>::
00377 generate_normalized(const automata_set_t& set,
00378 unsigned nb_state,
00379 unsigned density)
00380 {
00381 typedef typename TAutomata::state_iterator state_iterator;
00382 typedef typename TAutomata::monoid_t::alphabets_elt_t alphabets_elt_t;
00383
00384 if (density == 0)
00385 density = 1;
00386
00387 TAutomata work = generate(set, nb_state,
00388 nb_state + alea(nb_state * density));
00389
00390 for (state_iterator i = work.states().begin(); i != work.states().end();
00391 i++)
00392 {
00393 if (work.is_initial(*i))
00394 work.unset_initial(*i);
00395 if (work.is_final(*i))
00396 work.unset_final(*i);
00397 }
00398
00399 hstate_t init = work.add_state();
00400 hstate_t final = work.add_state();
00401
00402 work.set_initial(init);
00403 work.set_final(final);
00404
00405 const alphabets_elt_t&
00406 alpha = work.structure().series().monoid().alphabet();
00407
00408 hstate_t tmp;
00409
00410 for (unsigned i = 0; i < density; i++)
00411 if ((tmp = work.choose_state()) != init)
00412 work.add_letter_transition(init, tmp,
00413 alpha.choose());
00414
00415 for (unsigned i =0; i < density; i++)
00416 if ((tmp = work.choose_state()) != final)
00417 work.add_letter_transition(tmp, final,
00418 alpha.choose());
00419
00420 return work;
00421 }
00422
00423 }
00424
00425 }
00426
00427 #endif // ! VCSN_TOOLS_GEN_RANDOM_HXX