5 #include <boost/range/algorithm/mismatch.hpp> 39 template <
Automaton Aut,
typename ValueSet,
40 typename Mul,
typename GetValue>
52 using value_t =
typename valueset_t::value_t;
55 Mul mul, GetValue get_value)
59 , get_value_(get_value)
73 return vs_.less(v_, rhs.
v_);
91 template <Automaton AnyAut>
99 for (
auto t = path[dst];
100 t != aut->null_transition();
101 t = path[aut->src_of(t)])
104 if (aut->src_of(t) == src)
107 std::reverse(
res.begin(),
res.end());
117 template <Automaton AnyAut>
124 return algo(src, dst);
130 auto first = compute_lightest_path(aut_, src, dst);
131 auto res =
paths_t{path(aut_, first, src, dst)};
136 for (
unsigned i = 1
u; i < k; i++)
138 const auto& prev =
res[i - 1];
139 for (
unsigned j = 0
u; j < prev.size(); j++)
141 auto filter_aut = filter<automaton_t, true>(aut_);
142 filter_aut->unhide_all_states();
143 filter_aut->unhide_all_transition();
144 auto spur_node = filter_aut->src_of(prev[j]);
145 auto root_path =
path_t(prev.begin(), prev.begin() + j);
147 for (
const auto& selected_path:
res)
148 if (j < selected_path.size())
150 auto diff = std::mismatch(root_path.begin(),
152 selected_path.begin(),
153 selected_path.begin() + j);
154 if (diff.first == root_path.end()
155 && filter_aut->has_transition(selected_path[j]))
156 filter_aut->hide_transition(selected_path[j]);
159 for (
auto t: root_path)
160 if (t != filter_aut->null_transition()
161 && filter_aut->src_of(t) != spur_node
162 && filter_aut->src_of(t) != aut_->pre()
163 && filter_aut->has_state(filter_aut->src_of(t)))
164 filter_aut->hide_state(filter_aut->src_of(t));
167 = compute_lightest_path(filter_aut, spur_node, dst);
169 = path(filter_aut, shortest_path, spur_node, dst);
170 root_path.insert(root_path.end(),
171 spur_path.begin(), spur_path.end());
172 if (!root_path.empty()
173 && filter_aut->src_of(root_path.front()) == src
174 && filter_aut->dst_of(root_path.back()) == dst)
176 bool already_found =
false;
177 for (
const auto&
profile: heap)
180 if (root_path.size() == selected_path.size())
182 auto diff = boost::mismatch(root_path,
184 if (diff.first == root_path.end())
186 already_found =
true;
196 heap.emplace(std::move(root_path), vs_, get_value_(m));
202 res.push_back(heap.top().path_);
214 template <Automaton Aut,
typename ValueSet,
typename Mul,
typename GetValue>
216 make_yen(
const Aut& aut,
const ValueSet& vs, Mul mul, GetValue get_value)
219 (aut, vs, mul, get_value));
224 template <Automaton Aut>
225 std::vector<path_t_of<Aut>>
231 return aut->weightset()->mul(lhs, aut->weight_of(t));
233 auto get_value = [](
auto m) {
return m.second; };
235 return yen(src, dst, k);
244 template <Automaton Aut>
250 if (t != aut->null_transition())
251 res[aut->dst_of(t)] = t;
255 template <Automaton Aut>
std::vector< transition_t_of< Aut > > predecessors_t_of
A state-indexed vector of predecessor transitions from the path path.
auto path_monomial(const Aut &aut, const predecessors_t_of< Aut > &path, state_t_of< Aut > src=Aut::element_type::pre(), state_t_of< Aut > dst=Aut::element_type::post()) -> boost::optional< typename detail::word_polynomialset_t< context_t_of< Aut >>::monomial_t >
Given a path (typically computed by lightest_path), the corresponding monomial (label, weight).
yen_impl(const automaton_t &aut, const ValueSet &vs, Mul mul, GetValue get_value)
std::vector< transition_t_of< Aut > > path_t_of
A list of transitions representing a path.
std::vector< path_t > paths_t
typename detail::state_t_of_impl< base_t< ValueSet > >::type state_t_of
std::vector< path_t_of< Aut > > k_lightest_path(const Aut &aut, state_t_of< Aut > src, state_t_of< Aut > dst, unsigned k)
size_t states_size(const Aut &aut)
The largest state number, plus one.
state_t_of< automaton_t > state_t
path_t_of< AnyAut > path(const AnyAut &aut, const predecessors_t_of< AnyAut > &path, state_t_of< AnyAut > src=AnyAut::element_type::pre(), state_t_of< AnyAut > dst=AnyAut::element_type::post())
Transform a map transition_t -> transition_t representing the predecessors of each transition into a ...
paths_t operator()(state_t src, state_t dst, unsigned k)
mutable_automaton< Context > u(const Context &ctx, unsigned n)
The Brzozowski universal witness.
path_t_of< automaton_t > path_t
vcsn::min_fibonacci_heap< profile > heap_t
typename detail::weight_t_of_impl< base_t< ValueSet > >::type weight_t_of
predecessors_t_of< AnyAut > compute_lightest_path(const AnyAut &aut, state_t_of< AnyAut > src=Aut::element_type::pre(), state_t_of< AnyAut > dst=Aut::element_type::post())
Compute a lightest path on a part of the automaton.
auto make_word_polynomialset(const Ctx &ctx) -> word_polynomialset_t< Ctx >
The polynomialset of words of a labelset (not necessarily on words itself).
bool operator<(const profile &rhs) const
predecessors_t_of< Aut > format_lightest(const Aut &aut, const std::vector< transition_t_of< Aut >> &path)
A state-indexed vector of predecessor transitions from the path path.
auto make_yen(const Aut &aut, const ValueSet &vs, Mul mul, GetValue get_value)
transition_t_of< automaton_t > transition_t
std::vector< transition_t_of< Aut > > lightest_path(const Aut &aut, state_t_of< Aut > source, state_t_of< Aut > dest, a_star_tag)
Explicit path representation.
typename detail::transition_t_of_impl< base_t< ValueSet > >::type transition_t_of
weight_t_of< automaton_t > weight_t
boost::heap::fibonacci_heap< Elt, detail::comparator_t< Elt > > min_fibonacci_heap
auto make_dijkstra_impl(const Aut &aut, const ValueSet &vs, Mul mul)
Yen's algorithm of the K lightest paths.
typename valueset_t::value_t value_t
profile(const path_t &path, const valueset_t &vs, const value_t &v)
context_t_of< automaton_t > context_t
typename detail::context_t_of_impl< base_t< ValueSet > >::type context_t_of