gen_random.hxx

00001 // gen_random.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
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       | GenRandomAutomataSet |
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       | GenRandomAutomata |
00095       `------------------*/
00096 
00097     template <class TAutomata, class AutomataSetGenerator>
00098       GenRandomAutomata<TAutomata, AutomataSetGenerator>::GenRandomAutomata()
00099       {}
00100 
00101 
00102     /*------.
00103       | empty |
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       | generate |
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         // check consistency of automaton
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         // minimal construction
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         // set initial states
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         // set final states
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       | useful methods |
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       | generate with epsilon |
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       | generate dfa |
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         // set initial states
00339         work.set_initial(work.choose_state());
00340 
00341         // set final states
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       | generate normalized |
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   } // tools
00416 } // vcsn
00417 
00418 #endif // ! VCSN_TOOLS_GEN_RANDOM_HXX

Generated on Sun Jul 29 19:35:19 2007 for Vaucanson by  doxygen 1.5.2