Vcsn  2.8
Be Rational
bellman-ford.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <boost/optional.hpp>
4 
5 #include <vcsn/core/automaton.hh> // states_size
6 #include <vcsn/misc/set.hh>
7 #include <vcsn/weightset/fwd.hh>
8 
9 namespace vcsn
10 {
11  /*-----------------------------------------------.
12  | Shortest path through Bellman-Ford algorithm. |
13  `-----------------------------------------------*/
14 
18  struct bellman_ford_tag {};
19 
20  namespace detail
21  {
27  template <Automaton Aut>
28  boost::optional<predecessors_t_of<Aut>>
29  bellman_ford_impl(const Aut& aut, state_t_of<Aut> source)
30  {
31  auto size = states_size(aut);
32  auto dist = std::vector<weight_t_of<Aut>>(size);
33  auto res = predecessors_t_of<Aut>(size, aut->null_transition());
34  auto ws = *aut->weightset();
35 
36  dist[source] = ws.one();
37 
38  // Iterate once for each state over each transitions.
39  for (auto _: aut->all_states())
40  {
41  (void) _;
42  for (auto t: all_transitions(aut))
43  {
44  auto src = aut->src_of(t);
45 
46  if (res[src] != aut->null_transition() || src == source)
47  {
48  auto dst = aut->dst_of(t);
49  auto nw = ws.mul(dist[src], aut->weight_of(t));
50  if (res[dst] == aut->null_transition()
51  || ws.less(nw, dist[dst]))
52  {
53  dist[dst] = nw;
54  res[dst] = t;
55  }
56  }
57  }
58  }
59 
60  // Check for lightening cycles.
61  auto has_lightening_cycle = any_of(transitions(aut), [&](auto t) {
62  auto src = aut->src_of(t);
63  auto dst = aut->dst_of(t);
64  return (res[src] != aut->null_transition()
65  && (res[dst] == aut->null_transition()
66  || ws.less(ws.mul(dist[src], aut->weight_of(t)),
67  dist[dst])));
68  });
70  return boost::none;
71  else
72  return res;
73  }
74  }
75 
78  template <Automaton Aut>
82  {
83  auto res = bellman_ford_impl(aut, source);
84  require(res, "bellman-ford: automaton with negative cycle");
85  return std::move(*res);
86  }
87 }
auto all_transitions(const Aut &aut)
All the transition indexes between all states (including pre and post).
Definition: automaton.hh:214
bool any_of(const Range &r, Predicate p)
Definition: algorithm.hh:16
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
typename detail::state_t_of_impl< base_t< ValueSet > >::type state_t_of
Definition: traits.hh:64
size_t states_size(const Aut &aut)
The largest state number, plus one.
Definition: automaton.hh:41
std::enable_if_t< weightset_t_of< Aut >::has_lightening_weights(), bool > has_lightening_cycle(const Aut &aut)
std::vector< transition_t_of< Aut > > lightest_path(const Aut &aut, state_t_of< Aut > source, state_t_of< Aut > dest, a_star_tag)
Definition: a-star.hh:151
Definition: a-star.hh:8
std::vector< transition_t_of< Aut > > predecessors_t_of
A state-indexed vector of predecessor transitions from the path path.
Definition: automaton.hh:18
void require(Bool b, Args &&... args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:87
auto transitions(const Aut &aut) -> decltype(all_transitions(aut, is_special_t< Aut >
All the transition indexes between visible states.
Definition: automaton.hh:248
Bellman-Ford implementation (from vcsn/algos/bellman-ford.hh).
Definition: bellman-ford.hh:18
boost::optional< predecessors_t_of< Aut > > bellman_ford_impl(const Aut &aut, state_t_of< Aut > source)
Bellman-Ford implementation of lightest automaton.
Definition: bellman-ford.hh:29
return res
Definition: multiply.hh:399