Vcsn  2.5
Be Rational
shortest-path-tree.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vcsn/misc/map.hh>
5 #include <vcsn/ctx/traits.hh>
7 
8 namespace vcsn
9 {
10  namespace detail
11  {
17  template <typename Aut>
19  {
20  using automaton_t = Aut;
24  using dijkstra_map_t = std::unordered_map<state_t, dijkstra_node_t>;
25 
26  public:
28  : root_{root}
29  , aut_{aut}
30  {}
31 
32  void
33  add(const dijkstra_node_t& n)
34  {
35  states_[n.state_] = n;
36  }
37 
38  void
40  {
41  if (has(states_, s))
42  states_[s].set_parent(parent);
43  else
44  states_[s] = dijkstra_node_t{aut_, s, {}, parent};
45  }
46 
47  weight_t
49  {
50  auto it = states_.find(s);
51  if (it != states_.end())
52  return it->second.get_weight();
53  else
54  return aut_->weightset()->max();
55  }
56 
59  {
60  auto it = states_.find(s);
61  if (it == states_.end())
62  {
63  auto elt = dijkstra_node_t{aut_, s, {}, Aut::element_type::null_state()};
64  auto p = states_.emplace(s, elt);
65  it = p.first;
66  }
67  return it->second;
68  }
69 
70  state_t
72  {
73  auto it = states_.find(s);
74  if (it != states_.end())
75  return it->second.get_parent();
76  else
77  return automaton_t::element_type::null_state();
78  }
79 
80  state_t
82  {
83  auto it = states_.find(s);
84  if (it != states_.end())
85  return it->second.get_parent();
86  else
87  return automaton_t::element_type::null_state();
88  }
89 
90  state_t
91  get_root() const
92  {
93  return root_;
94  }
95 
97  {
98  return states_[s];
99  }
100 
101  private:
105  };
106 
112  template <typename Aut>
115  {
116  using automaton_t = Aut;
119  using handle_t = typename queue_t::handle_type;
120  auto handles = std::unordered_map<state_t_of<automaton_t>, handle_t>{};
121 
122  auto predecessor_tree = shortest_path_tree<automaton_t>(aut, src);
123  auto queue = queue_t{};
124  auto& src_node = predecessor_tree.get_node_of(predecessor_tree.get_root());
126  src_node.set_depth(0);
127  handles[src_node.get_state()] = queue.emplace(src_node);
128 
129  const auto& ws = *aut->weightset();
130  while (!queue.empty())
131  {
132  auto current = std::move(queue.top());
133  queue.pop();
134  auto s = current.get_state();
135  // This saves us very little time compared to retrieval at each iteration.
136  const auto curr_weight = current.get_weight();
137  const auto curr_depth = current.get_depth();
138 
139  for (auto tr : all_in(aut, s))
140  {
141  auto& neighbor = predecessor_tree.get_node_of(aut->src_of(tr));
142  auto dist = neighbor.get_weight();
143  // In the case of Nmin, this computation is costly because of the
144  // further verification on whether lhs or rhs is max_int but using
145  // lhs + rhs would disable genericity.
146  auto new_dist = ws.mul(curr_weight, aut->weight_of(tr));
147  if (ws.less(new_dist, dist))
148  {
149  neighbor.set_weight(new_dist);
150  neighbor.set_depth(curr_depth + 1);
151  neighbor.set_parent(s);
152  auto p = handles.emplace(neighbor.get_state(), handle_t{});
153  if (p.second)
154  p.first->second = queue.emplace(neighbor);
155  else
156  queue.update(p.first->second);
157  }
158  }
159  }
160  return predecessor_tree;
161  }
162  }
163 }
state_t get_parent_of(state_t s) const
dijkstra_node_t & get_node_of(state_t s)
ATTRIBUTE_PURE bool has(const boost::container::flat_set< Key, Compare, Allocator > &s, const Key &e)
Whether e is member of s.
Definition: setalpha.hh:25
shortest_path_tree< Aut > compute_shortest_path_tree(const Aut &aut, state_t_of< Aut > src)
Compute the shortest path tree of aut starting from src.
Definition: a-star.hh:8
weight_t_of< automaton_t > weight_t
weight_t get_weight() const
If there is no weight in the node then its weight is the weightset&#39;s maximum.
typename detail::state_t_of_impl< base_t< ValueSet > >::type state_t_of
Definition: traits.hh:64
void set_weight(weight_t weight)
dijkstra_node_t & operator[](state_t s)
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
Definition: traits.hh:67
typename detail::weight_t_of_impl< base_t< ValueSet > >::type weight_t_of
Definition: traits.hh:66
dijkstra_node< automaton_t > dijkstra_node_t
state_t_of< automaton_t > state_t
boost::heap::fibonacci_heap< Elt, detail::comparator_t< Elt > > min_fibonacci_heap
std::unordered_map< state_t, dijkstra_node_t > dijkstra_map_t
Dijkstra Node implementation.
void set_parent_of(state_t s, state_t parent)
auto all_in(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions entering state s.
Definition: automaton.hh:116
void add(const dijkstra_node_t &n)
shortest_path_tree(const automaton_t &aut, state_t root)