Vcsn  2.8
Be Rational
dijkstra.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vcsn/algos/tags.hh>
6 
7 namespace vcsn
8 {
9 
10  /*-------------------------------------------.
11  | Shortest path through Dijkstra algorithm. |
12  `-------------------------------------------*/
13 
14  namespace detail
15  {
29  template <Automaton Aut, typename ValueSet, typename Mul>
31  {
32  using automaton_t = Aut;
41  using valueset_t = ValueSet;
42  using value_t = typename valueset_t::value_t;
43  using distance_t = std::vector<value_t>;
44 
45  dijkstra_impl(const Aut& aut, const ValueSet& vs, Mul mul)
46  : aut_(aut)
47  , res_(states_size(aut_), aut_->null_transition())
49  , vs_{vs}
50  , mul_{mul}
51  {};
52 
53  struct profile
54  {
55  profile(state_t state, const self_t& d)
56  : state_(state)
57  , self_(d)
58  {}
59 
60  bool operator<(const profile& rhs) const
61  {
62  if (self_.res_[rhs.state_] == self_.aut_->null_transition())
63  return true;
64  else if (self_.res_[state_] == self_.aut_->null_transition())
65  return false;
66  else
67  return self_.vs_.less(self_.dist_[state_], self_.dist_[rhs.state_]);
68  }
69 
71  const self_t& self_;
72  };
73 
75 
77  operator()(state_t source, state_t dest)
78  {
79  // FIXME: this will not work if the automaton is lazy. We
80  // must _never_ depend on states_size. We really need
81  // something like state_map_t that is able to grow on demand
82  // with lazy automata.
83  auto size = states_size(aut_);
84  auto handles = std::vector<typename heap_t::handle_type>(size);
85  auto todo = heap_t();
86 
87  dist_[source] = vs_.one();
88  handles[source] = todo.emplace(source, *this);
89 
90  while (!todo.empty())
91  {
92  auto p = todo.top();
93  todo.pop();
94  state_t s = p.state_;
95  if (s == dest)
96  break;
97  else
98  for (auto t: all_out(aut_, s))
99  {
100  auto dst = aut_->dst_of(t);
101  auto nv = mul_(dist_[s], t);
102  if (res_[dst] == aut_->null_transition())
103  {
104  // First visit.
105  dist_[dst] = nv;
106  res_[dst] = t;
107  handles[dst] = todo.emplace(dst, *this);
108  }
109  else if (vs_.less(nv, dist_[dst]))
110  {
111  // Lighter path.
112  dist_[dst] = nv;
113  res_[dst] = t;
114  todo.update(handles[dst]);
115  }
116  }
117  }
118  return std::move(res_);
119  }
120 
121  public:
126  const ValueSet& vs_;
127  Mul mul_;
128  };
129 
130  template <Automaton Aut, typename ValueSet, typename Mul>
131  auto
132  make_dijkstra_impl(const Aut& aut, const ValueSet& vs, Mul mul)
133  {
134  return dijkstra_impl<Aut, ValueSet, Mul>(aut, vs, mul);
135  }
136  }
137 
138  template <Automaton Aut>
140  lightest_path(const Aut& aut, state_t_of<Aut> source, state_t_of<Aut> dest,
141  dijkstra_tag)
142  {
143  auto get_value = [&aut](auto lhs, transition_t_of<Aut> t)
144  {
145  return aut->weightset()->mul(lhs, aut->weight_of(t));
146  };
147  auto algo = detail::make_dijkstra_impl(aut, *aut->weightset(), get_value);
148  return algo(source, dest);
149  }
150 }
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
Definition: traits.hh:67
predecessors_t_of< automaton_t > res_
For each state, its predecessor.
Definition: dijkstra.hh:124
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
typename detail::transition_t_of_impl< base_t< ValueSet > >::type transition_t_of
Definition: traits.hh:65
transition_t_of< automaton_t > transition_t
Definition: dijkstra.hh:35
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
profile(state_t state, const self_t &d)
Definition: dijkstra.hh:55
typename valueset_t::value_t value_t
Definition: dijkstra.hh:42
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
Definition: automaton.hh:67
typename detail::context_t_of_impl< base_t< ValueSet > >::type context_t_of
Definition: traits.hh:61
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
const ValueSet & vs_
Definition: dijkstra.hh:126
Definition: a-star.hh:8
const automaton_t & aut_
Definition: dijkstra.hh:122
Dijkstra implementation.
Definition: tags.hh:144
typename detail::label_t_of_impl< base_t< ValueSet > >::type label_t_of
Definition: traits.hh:62
weightset_t_of< automaton_t > weightset_t
Definition: dijkstra.hh:38
state_t_of< automaton_t > state_t
Definition: dijkstra.hh:34
vcsn::min_fibonacci_heap< profile > heap_t
Definition: dijkstra.hh:74
context_t_of< automaton_t > context_t
Definition: dijkstra.hh:39
auto make_dijkstra_impl(const Aut &aut, const ValueSet &vs, Mul mul)
Definition: dijkstra.hh:132
weight_t_of< automaton_t > weight_t
Definition: dijkstra.hh:37
bool operator<(const profile &rhs) const
Definition: dijkstra.hh:60
boost::heap::fibonacci_heap< Elt, detail::comparator_t< Elt > > min_fibonacci_heap
label_t_of< automaton_t > label_t
Definition: dijkstra.hh:36
std::vector< transition_t_of< Aut > > predecessors_t_of
A state-indexed vector of predecessor transitions from the path path.
Definition: automaton.hh:18
predecessors_t_of< automaton_t > operator()(state_t source, state_t dest)
Definition: dijkstra.hh:77
typename detail::weight_t_of_impl< base_t< ValueSet > >::type weight_t_of
Definition: traits.hh:66
dijkstra_impl(const Aut &aut, const ValueSet &vs, Mul mul)
Definition: dijkstra.hh:45
std::vector< value_t > distance_t
Definition: dijkstra.hh:43
Dijkstra implementation of lightest automaton.
Definition: dijkstra.hh:30