00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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
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
00077
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
00112 std::map<hstate_t,std::list<monoid_elt_t> > theword;
00113
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
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 }
00190
00191 #endif // ! VCSN_ALGORITHMS_SHORTEST_HXX