- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# shortest.hxx

    00001 // shortest.hh: this file is part of the Vaucanson project.
    00002 //
    00003 // Vaucanson, a generic library for finite state machines.
    00004 //
    00005 // Copyright (C) 2008, 2009, 2010 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_ALGORITHMS_SHORTEST_HXX
    00018 # define VCSN_ALGORITHMS_SHORTEST_HXX
    00019
    00020 #include <vaucanson/algorithms/shortest.hh>
    00021 #include <vaucanson/automata/concept/automata_base.hh>
    00022 #include <vaucanson/misc/usual_macros.hh>
    00023 #include <queue>
    00024 #include <map>
    00025 #include <vaucanson/misc/military_order.hh>
    00026 #include <vaucanson/algorithms/shortest.hh>
    00027
    00028 namespace vcsn
    00029 {
    00030   template<typename Automaton, typename MonoidElt>
    00031   bool
    00032   do_shortest(const Automaton& autom, MonoidElt& word)
    00033   {
    00034     precondition(is_realtime(autom));
    00035     AUTOMATON_TYPES(Automaton);
    00036     AUTOMATON_FREEMONOID_TYPES (Automaton);
    00037
    00038     monoid_t themonoid = autom.structure().series().monoid();
    00039     // shortest word read at this state
    00040     typedef std::map<hstate_t, monoid_elt_t> theword_t;
    00041     theword_t theword;
    00042     std::queue<hstate_t> thequeue;
    00043
    00044     monoid_elt_t empty_word = themonoid.identity(SELECT(monoid_elt_value_t));
    00045
    00046     for_all_initial_states(j, autom)
    00047       {
    00048         theword.insert(std::pair<hstate_t,monoid_elt_t>(*j, empty_word));
    00049         if (autom.is_final(*j))
    00050           {
    00051             word = empty_word;
    00052             return true;
    00053           }
    00054         thequeue.push(*j);
    00055       }
    00056
    00057     while (not thequeue.empty())
    00058       {
    00059         hstate_t i = thequeue.front();
    00060         thequeue.pop();
    00061         for_all_letters(a, themonoid.alphabet())
    00062           {
    00063             for (typename Automaton::delta_iterator t(autom.value(), i);
    00064                  ! t.done();
    00065                  t.next())
    00066               {
    00067                 // iterate over successors of i by *a
    00068                 monoid_elt_t w(themonoid, *a);
    00069                 if (autom.series_of(*t).get(w)
    00070                     != autom.series().semiring()
    00071                        .zero(SELECT(typename semiring_elt_t::value_t)))
    00072                   {
    00073                     hstate_t j = autom.dst_of(*t);
    00074                     if (theword.find(j) == theword.end())
    00075                       {
    00076                         // j is in the map only if it has been seen
    00077                         // before, otherwise:
    00078
    00079                         typename theword_t::const_iterator k = theword.find(i);
    00080                         assert(k != theword.end());
    00081
    00082                         theword.insert(std::pair<hstate_t, monoid_elt_t>(j, k->second * (*a)));
    00083                         if (autom.is_final(j))
    00084                           {
    00085                             typename theword_t::const_iterator k = theword.find(j);
    00086                             assert(k != theword.end());
    00087
    00088                             word = k->second;
    00089                             return true;
    00090                           }
    00091                         thequeue.push(j);
    00092                       }
    00093                   }
    00094               }
    00095           }
    00096       }
    00097     return false;
    00098   }
    00099
    00100   template<typename Automaton, typename MonoidElt, typename Alloc>
    00101   void
    00102   do_enumerate(const Automaton& autom,
    00103                unsigned max_length,
    00104                std::list<MonoidElt, Alloc>& words)
    00105   {
    00106     precondition(is_realtime(autom));
    00107
    00108     AUTOMATON_TYPES(Automaton);
    00109     AUTOMATON_FREEMONOID_TYPES (Automaton);
    00110     monoid_t themonoid = autom.structure().series().monoid();
    00111     // a list of words that leads to this state
    00112     std::map<hstate_t,std::list<monoid_elt_t> > theword;
    00113     //std::list allows swap, contrary to std::queue
    00114     std::list<std::pair<hstate_t,monoid_elt_t> > queue1;
    00115     std::list<std::pair<hstate_t,monoid_elt_t> > queue2;
    00116
    00117     monoid_elt_t empty_word = themonoid.identity(SELECT(monoid_elt_value_t));
    00118
    00119     for_all_initial_states(j, autom)
    00120       {
    00121         theword[*j].push_back(empty_word);
    00122         queue1.push_back(std::pair<hstate_t,monoid_elt_t>(*j, empty_word));
    00123       }
    00124
    00125     for(unsigned i = 0; i < max_length && not queue1.empty(); i++)
    00126       {
    00127         while (not queue1.empty())
    00128           {
    00129             std::pair<hstate_t,monoid_elt_t> thepair = queue1.front();
    00130             queue1.pop_front();
    00131             hstate_t s = thepair.first;
    00132             monoid_elt_t oldword = thepair.second;
    00133             for (typename Automaton::delta_iterator t(autom.value(), s);
    00134                  ! t.done();
    00135                  t.next())
    00136               {
    00137                 for_all_letters(a, themonoid.alphabet())
    00138                   {
    00139                     // iterate over successors of i by *a
    00140                     monoid_elt_t w(themonoid, *a);
    00141                     if (autom.series_of(*t).get(w) !=
    00142                         autom.series().semiring().zero(SELECT(typename semiring_elt_t::value_t)))
    00143                       {
    00144                         monoid_elt_t newword = oldword *(*a);
    00145                         theword[autom.dst_of(*t)].push_back(newword);
    00146                         queue2.push_back(std::pair<hstate_t,monoid_elt_t>(autom.dst_of(*t),newword));
    00147                       }
    00148                   }
    00149               }
    00150           }
    00151         queue1.swap(queue2);
    00152       }
    00153
    00154     std::vector<monoid_elt_t> v;
    00155     for_all_final_states(j, autom)
    00156       {
    00157         std::list<monoid_elt_t> &l = theword[*j];
    00158         v.insert(v.end(), l.begin(), l.end());
    00159       }
    00160     sort(v.begin(), v.end(), MilitaryOrder<monoid_elt_t>());
    00161     typename std::vector<monoid_elt_t>::iterator v_last
    00162       = std::unique(v.begin(), v.end());
    00163     words.insert(words.begin(), v.begin(), v_last);
    00164   }
    00165
    00166   template<typename Automaton>
    00167   typename Automaton::monoid_elt_t
    00168   shortest(const Automaton& autom)
    00169   {
    00170     typename Automaton::monoid_elt_t word(autom.structure().series().monoid());
    00171     do_shortest(autom, word);
    00172     return word;
    00173   }
    00174
    00175   template<typename Automaton, typename MonoidElt>
    00176   bool
    00177   shortest(const Automaton& autom, MonoidElt& word)
    00178   {
    00179     return do_shortest(autom, word);
    00180   }
    00181
    00182   template<typename Automaton, typename MonoidElt, typename Alloc>
    00183   void
    00184   enumerate(const Automaton& autom, unsigned max_length,
    00185             std::list<MonoidElt, Alloc>& word_list)
    00186   {
    00187     do_enumerate(autom, max_length, word_list);
    00188   }
    00189 } // ! vcsn
    00190
    00191 #endif // ! VCSN_ALGORITHMS_SHORTEST_HXX