Vcsn  2.8
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 map_t = std::unordered_map<state_t, node_t>;
25 
26  public:
28  : root_{root}
29  , aut_{aut}
30  {
31  compute_();
32  }
33 
34  void
35  add(const node_t& n)
36  {
37  states_[n.state_] = n;
38  }
39 
40  void
42  {
43  if (has(states_, s))
44  states_[s].set_parent(parent);
45  else
46  states_[s] = node_t{aut_, s, parent};
47  }
48 
49  weight_t
51  {
52  auto it = states_.find(s);
53  if (it == states_.end())
54  return aut_->weightset()->max();
55  else
56  return it->second.get_weight();
57  }
58 
59  node_t&
61  {
62  auto it = states_.find(s);
63  if (it == states_.end())
64  {
65  auto elt = node_t{aut_, s, aut_->null_state()};
66  auto p = states_.emplace(s, elt);
67  it = p.first;
68  }
69  return it->second;
70  }
71 
72  state_t
74  {
75  auto it = states_.find(s);
76  if (it == states_.end())
77  return aut_->null_state();
78  else
79  return it->second.get_parent();
80  }
81 
82  state_t
83  get_root() const
84  {
85  return root_;
86  }
87 
89  {
90  return states_[s];
91  }
92 
93  private:
100  void
102  {
103  using queue_t = vcsn::min_fibonacci_heap<node_t>;
104  using handle_t = typename queue_t::handle_type;
105  auto handles = std::unordered_map<state_t_of<automaton_t>, handle_t>{};
106 
107  auto queue = queue_t{};
108  auto& src_node = get_node_of(get_root());
109  src_node.set_weight(weightset_t_of<automaton_t>::one());
110  src_node.set_depth(0);
111  handles[src_node.get_state()] = queue.emplace(src_node);
112 
113  const auto& ws = *aut_->weightset();
114  while (!queue.empty())
115  {
116  auto current = std::move(queue.top());
117  queue.pop();
118  auto s = current.get_state();
119  // This saves us very little time compared to retrieval at
120  // each iteration.
121  const auto curr_weight = current.get_weight();
122  const auto curr_depth = current.get_depth();
123 
124  for (auto t: all_in(aut_, s))
125  {
126  auto& neighbor = get_node_of(aut_->src_of(t));
127  auto dist = neighbor.get_weight();
128  // In the case of Nmin, this computation is costly because of the
129  // further verification on whether lhs or rhs is max_int but using
130  // lhs + rhs would disable genericity.
131  auto new_dist = ws.mul(curr_weight, aut_->weight_of(t));
132  if (ws.less(new_dist, dist))
133  {
134  neighbor.set_weight(new_dist);
135  neighbor.set_depth(curr_depth + 1);
136  neighbor.set_parent(s);
137  auto p = handles.emplace(neighbor.get_state(), handle_t{});
138  if (p.second)
139  p.first->second = queue.emplace(neighbor);
140  else
141  queue.update(p.first->second);
142  }
143  }
144  }
145  }
146 
150  };
151 
152  template <typename Aut>
155  {
156  return {aut, root};
157  }
158  }
159 }
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:26
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
Definition: traits.hh:67
weight_t_of< automaton_t > weight_t
void set_parent_of(state_t s, state_t parent)
typename detail::state_t_of_impl< base_t< ValueSet > >::type state_t_of
Definition: traits.hh:64
shortest_path_tree(const automaton_t &aut, state_t root)
state_t_of< automaton_t > state_t
weight_t get_weight() const
If there is no weight in the node then its weight is the weightset&#39;s maximum.
weight_t get_weight_of(state_t s) const
auto all_in(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions entering state s.
Definition: automaton.hh:116
shortest_path_tree< Aut > make_shortest_path_tree(const Aut &aut, state_t_of< Aut > root)
Definition: a-star.hh:8
Dijkstra Node implementation.
state_t get_parent_of(state_t s) const
boost::heap::fibonacci_heap< Elt, detail::comparator_t< Elt > > min_fibonacci_heap
std::unordered_map< state_t, node_t > map_t
typename detail::weight_t_of_impl< base_t< ValueSet > >::type weight_t_of
Definition: traits.hh:66
void compute_()
Compute the shortest path tree of aut_ starting from root_.