00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_AUT_TO_EXP_HXX
00018 # define VCSN_ALGORITHMS_AUT_TO_EXP_HXX
00019
00020 # include <vaucanson/algorithms/aut_to_exp.hh>
00021
00022 # include <vaucanson/automata/concept/handlers.hh>
00023 # include <vaucanson/algorithms/normalized.hh>
00024 # include <vaucanson/misc/usual_macros.hh>
00025 # include <vaucanson/misc/contract.hh>
00026 # include <vaucanson/misc/limits.hh>
00027 # include <vaucanson/misc/random.hh>
00028 # include <vaucanson/automata/concept/automata_base.hh>
00029
00030 # include <list>
00031 # include <set>
00032 # include <vector>
00033
00034 # include <stdlib.h>
00035 # include <time.h>
00036
00037 namespace vcsn {
00038
00039
00040
00041
00042
00043 template <class Auto_>
00044 hstate_t
00045 DefaultChooser::operator()(const Auto_& a) const
00046 {
00047 assertion(a.states().size() > 0);
00048 typename Auto_::state_iterator s = a.states().begin();
00049 typename Auto_::state_iterator k = s;
00050 while ((k != a.states().end()) &&
00051 ((a.is_initial(*k)) || (a.is_final(*k))))
00052 ++k;
00053 s = k;
00054 return *s;
00055 }
00056
00057
00058
00059
00060
00061
00062 template <class Auto_>
00063 hstate_t
00064 RandomChooser::operator()(const Auto_& a) const
00065 {
00066 assertion(a.states().size() > 0);
00067
00068 int n_init = 0;
00069 int n_final = 0;
00070 for (typename Auto_::state_iterator i = a.states().begin();
00071 i != a.states().end();
00072 ++i)
00073 {
00074 if (a.is_initial(*i))
00075 ++n_init;
00076 if (a.is_final(*i))
00077 ++n_final;
00078 }
00079
00080 unsigned n = misc::random::generate((unsigned) 0,
00081 a.states().size() -
00082 (n_init + n_final));
00083
00084 typename Auto_::state_iterator k = a.states().begin();
00085 unsigned kk = 0;
00086 while (kk <= n || k == a.states().end() ||
00087 ((a.is_initial(*k)) || (a.is_final(*k))))
00088 {
00089 if (k == a.states().end())
00090 {
00091 k = a.states().begin();
00092 continue;
00093 }
00094 ++k;
00095 ++kk;
00096 }
00097 return *k;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106 template <class Auto_>
00107 hstate_t
00108 HChooser::operator()(const Auto_& a) const
00109 {
00110 assertion(a.states().size() > 0);
00111
00112 std::set<htransition_t> delta_in;
00113 std::set<htransition_t> delta_out;
00114
00115 typename Auto_::state_iterator s = a.states().begin();
00116 unsigned int d_in = 0;
00117 unsigned int d_out = 0;
00118 unsigned int max = INT_MAX;
00119 bool has_loop = false;
00120 bool has_loop_old = false;
00121
00122 for (typename Auto_::state_iterator i = a.states().begin();
00123 i != a.states().end();
00124 ++i)
00125 {
00126 if (a.is_final(*i) || a.is_initial(*i))
00127 continue;
00128 has_loop = false;
00129
00130 a.deltac(delta_out, *i, delta_kind::transitions());
00131 a.rdeltac(delta_in, *i, delta_kind::transitions());
00132 for (typename std::set<htransition_t>::iterator j = delta_out.begin();
00133 j != delta_out.end();
00134 ++j)
00135 if (*i == a.dst_of(*j))
00136 has_loop = true;
00137
00138
00139 if (has_loop)
00140 d_in = delta_in.size() - 1;
00141 else
00142 d_in = delta_in.size();
00143 d_out = delta_out.size();
00144
00145
00146 if (d_in * d_out < max ||
00147 (d_in * d_out == max &&
00148 has_loop_old && not has_loop))
00149 {
00150 s = i;
00151 max = d_in * d_out;
00152 has_loop_old = has_loop;
00153 }
00154 delta_out.clear();
00155 delta_in.clear();
00156 }
00157 return *s;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 template <class Auto_>
00169 hstate_t
00170 DMChooser::operator()(const Auto_& a) const
00171 {
00172 assertion(a.states().size() > 0);
00173
00174 std::set<htransition_t> delta_in;
00175 std::set<htransition_t> delta_out;
00176 typename Auto_::state_iterator s = a.states().begin();
00177
00178 unsigned int weight_min = INT_MAX;
00179 for (typename Auto_::state_iterator i = a.states().begin();
00180 i != a.states().end();
00181 ++i)
00182 {
00183 if (a.is_final(*i) || a.is_initial(*i))
00184 continue;
00185 unsigned int n_loops = 0;
00186 unsigned int in = 0;
00187 unsigned int out = 0;
00188
00189 unsigned int weight = 0;
00190
00191 delta_in.clear();
00192 delta_out.clear();
00193 a.deltac(delta_out, *i, delta_kind::transitions());
00194 a.rdeltac(delta_in, *i, delta_kind::transitions());
00195
00196 for (typename std::set<htransition_t>::iterator j = delta_out.begin();
00197 j != delta_out.end();
00198 ++j)
00199 if (*i == a.dst_of(*j))
00200 ++n_loops;
00201
00202 in = delta_in.size() - n_loops;
00203 out = delta_out.size() - n_loops;
00204
00205
00206 for (typename std::set<htransition_t>::iterator j = delta_in.begin();
00207 j != delta_in.end();
00208 ++j)
00209 if (*i != a.dst_of(*j))
00210 {
00211 weight += a.series_value_of(*j).length() * (out - 1);
00212 }
00213
00214
00215 for (typename std::set<htransition_t>::iterator j = delta_out.begin();
00216 j != delta_out.end();
00217 ++j)
00218 if (*i != a.dst_of(*j))
00219 {
00220 weight += a.series_value_of(*j).length() * (in - 1);
00221 }
00222
00223
00224 for (typename std::set<htransition_t>::iterator j = delta_out.begin();
00225 j != delta_out.end();
00226 ++j)
00227 if (*i == a.dst_of(*j))
00228 {
00229 weight += a.series_value_of(*j).length() * (in * out - 1);
00230 }
00231
00232 if (weight < weight_min)
00233 {
00234 s = i;
00235 weight_min = weight;
00236 }
00237 }
00238 return *s;
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248 inline ListChooser::ListChooser(const std::list<hstate_t>& l) :
00249 list_(l),
00250 pos_(l.begin())
00251 {
00252 }
00253
00254 template <class Auto_>
00255 hstate_t
00256 ListChooser::operator() (const Auto_&)
00257 {
00258 assertion(pos_ != list_.end());
00259 return *pos_++;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268 template <class A_, typename Auto_, typename Chooser_>
00269 typename Auto_::series_set_elt_t
00270 do_in_aut_to_exp(const AutomataBase<A_>& a_set,
00271 Auto_& a,
00272 Chooser_ chooser)
00273 {
00274 AUTOMATON_TYPES(Auto_);
00275 typedef Auto_ automaton_t;
00276 typedef typename automaton_t::series_set_t series_set_t;
00277 typedef typename automaton_t::series_set_elt_t series_set_elt_t;
00278
00279 typedef typename std::set<htransition_t> htransition_set_t;
00280 typedef std::map<hstate_t, series_set_elt_t> sums_t;
00281
00282 typename htransition_set_t::const_iterator i, j;
00283 hstate_t q;
00284 htransition_set_t transitions;
00285 std::list<htransition_t> transitions_to_remove;
00286 normalize_here(a);
00287 precondition(is_normalized(a));
00288
00289 while (a.states().size() != 2)
00290 {
00291 series_set_elt_t loop_sum(a_set.series());
00292 sums_t in_sums, out_sums;
00293
00294 q = chooser(a);
00295 if (a.is_initial(q) || a.is_final(q))
00296 continue;
00297
00298 transitions.clear();
00299
00300 a.deltac(transitions, q, delta_kind::transitions());
00301 for (i = transitions.begin(); i != transitions.end(); i = j)
00302 {
00303 j = i; ++j;
00304
00305 if (a.dst_of(*i) == q)
00306 loop_sum += a.series_of(*i);
00307 else
00308 {
00309 typename sums_t::iterator f = out_sums.find(a.dst_of(*i));
00310 if (f == out_sums.end())
00311 f = out_sums.insert
00312 (std::make_pair(a.dst_of(*i),
00313 series_set_elt_t(a_set.series()))).first;
00314 f->second += a.series_of(*i);
00315 }
00316 a.del_transition(*i);
00317 }
00318 transitions.clear();
00319
00320 a.rdeltac(transitions, q, delta_kind::transitions());
00321 for (i = transitions.begin(); i != transitions.end(); i = j)
00322 {
00323 j = i; ++j;
00324
00325 typename sums_t::iterator f = in_sums.find(a.src_of(*i));
00326 if (f == in_sums.end())
00327 f = in_sums.insert
00328 (std::make_pair(a.src_of(*i),
00329 series_set_elt_t(a_set.series()))).first;
00330
00331 f->second += a.series_of(*i);
00332 a.del_transition(*i);
00333 }
00334 loop_sum.star();
00335
00336 for_all_const_(sums_t, in, in_sums)
00337 for_all_const_(sums_t, out, out_sums)
00338 {
00339 series_set_elt_t res = in->second * loop_sum * out->second;
00340 a.add_series_transition(in->first, out->first, res);
00341 }
00342 a.del_state(q);
00343 }
00344 series_set_elt_t final(a_set.series());
00345 for_all_transitions(i, a)
00346 final += a.label_of(*i);
00347 return final;
00348 }
00349
00350
00351
00352
00353
00354 template<typename A, typename T, typename Chooser_>
00355 typename Element<A, T>::series_set_elt_t
00356 aut_to_exp(const Element<A, T>& a, const Chooser_& c)
00357 {
00358 TIMER_SCOPED("aut_to_exp");
00359 Element<A, T> ret(a);
00360 return do_in_aut_to_exp(ret.structure(), ret, c);
00361 }
00362
00363 template<typename A, typename T>
00364 typename Element<A, T>::series_set_elt_t
00365 aut_to_exp(const Element<A, T>& a)
00366 {
00367 return aut_to_exp(a, DefaultChooser());
00368 }
00369
00370 }
00371
00372 #endif // ! VCSN_ALGORITHMS_AUT_TO_EXP_HXX