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