Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
distance.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_DISTANCE_HH
2 # define VCSN_ALGOS_DISTANCE_HH
3 
4 # include <algorithm>
5 # include <iostream>
6 # include <queue>
7 # include <unordered_set>
8 # include <unordered_map>
9 # include <vector>
10 
11 # include <vcsn/algos/copy.hh>
12 # include <vcsn/ctx/context.hh>
13 # include <vcsn/dyn/label.hh>
14 # include <vcsn/misc/pair.hh>
15 
16 namespace vcsn
17 {
21  template <typename Aut>
22  std::unordered_map<state_t_of<Aut>, weight_t_of<Aut>>
24  {
25  using weight_t = weight_t_of<Aut>;
26  using state_t = state_t_of<Aut>;
27 
28  std::unordered_map<state_t, weight_t> d;
29  std::unordered_map<state_t, weight_t> r;
30  auto ws = *aut->weightset();
31  for (auto s : aut->all_states())
32  {
33  d.emplace(s, ws.zero());
34  r.emplace(s, ws.zero());
35  }
36 
37  std::queue<state_t> todos;
38  std::unordered_set<state_t> marked;
39  d[s0] = ws.one();
40  r[s0] = ws.one();
41  todos.emplace(s0);
42  marked.emplace(s0);
43  while (!todos.empty())
44  {
45  auto s = todos.front();
46  todos.pop();
47  auto r1 = r[s];
48  r[s] = ws.zero();
49  for (auto t : aut->all_out(s))
50  {
51  auto dst = aut->dst_of(t);
52  auto w1 = ws.mul(r1, aut->weight_of(t));
53  auto w = ws.add(d[dst], w1);
54  if (!ws.equals(d[dst], w))
55  {
56  d[dst] = w;
57  r[dst] = ws.add(r[dst], w1);
58  if (!has(marked, dst))
59  {
60  todos.emplace(dst);
61  marked.emplace(dst);
62  }
63  }
64  }
65  }
66  d[s0] = ws.one();
67  return d;
68  }
69 
70  template<typename Aut>
71  std::unordered_map<state_t_of<Aut>,
72  std::pair<unsigned,
73  transition_t_of<Aut>>>
74  paths_ibfs(const Aut& aut, std::vector<state_t_of<Aut>> start)
75  {
76  using context_t = context_t_of<Aut>;
77  using automaton_t = mutable_automaton<context_t>;
78  using state_t = state_t_of<automaton_t>;
79  using transition_t = transition_t_of<automaton_t>;
80 
81  std::queue<state_t> todo;
82  std::unordered_set<state_t> marked;
83  std::unordered_map<state_t, std::pair<state_t, transition_t>> parent;
84 
85  for (auto s : start)
86  todo.push(s);
87 
88  while (!todo.empty())
89  {
90  state_t p = todo.front();
91  todo.pop();
92  marked.insert(p);
93  for (auto t : aut->all_in(p))
94  {
95  auto s = aut->src_of(t);
96  if (marked.find(s) == marked.end())
97  {
98  todo.push(s);
99  auto cur_p = parent.find(p);
100  unsigned cur_d;
101  if (cur_p == parent.end())
102  cur_d = 1;
103  else
104  cur_d = cur_p->second.first + 1;
105  parent[s] = {cur_d, t};
106  }
107  }
108  }
109  return parent;
110  }
111 
117  template<typename Aut>
118  std::vector<transition_t_of<Aut>>
119  path_bfs(const Aut& aut,
120  state_t_of<Aut> start, state_t_of<Aut> end)
121  {
122  using context_t = context_t_of<Aut>;
123  using automaton_t = mutable_automaton<context_t>;
124  using state_t = state_t_of<automaton_t>;
125  using transition_t = transition_t_of<automaton_t>;
126 
127  std::queue<state_t> todo;
128  std::unordered_set<state_t> marked;
129  std::unordered_map<state_t, std::pair<state_t, transition_t>> parent;
130 
131  todo.push(start);
132  while (!todo.empty())
133  {
134  state_t p = todo.front();
135  todo.pop();
136  marked.insert(p);
137  if (p == end)
138  {
139  std::vector<transition_t> rpath;
140  state_t bt_curr = end;
141  while (bt_curr != start)
142  {
143  transition_t t;
144  std::tie(bt_curr, t) = parent.find(bt_curr)->second;
145  rpath.push_back(t);
146  }
147  std::reverse(rpath.begin(), rpath.end());
148  return rpath;
149  }
150  else
151  for (auto t : aut->all_out(p))
152  {
153  auto s = aut->dst_of(t);
154  if (marked.find(s) == marked.end())
155  {
156  todo.push(s);
157  parent[s] = {p, t};
158  }
159  }
160  }
161  // FIXME: why don't we raise here?
162  return std::vector<transition_t>();
163  }
164 }
165 
166 #endif // !VCSN_ALGOS_DISTANCE_HH
std::vector< transition_t_of< Aut > > path_bfs(const Aut &aut, state_t_of< Aut > start, state_t_of< Aut > end)
A shortest path between two states.
Definition: distance.hh:119
pair_automaton< Aut > pair(const Aut &aut, bool keep_initials=false)
Definition: pair.hh:214
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
Definition: fwd.hh:25
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:32
std::unordered_map< state_t_of< Aut >, weight_t_of< Aut > > ss_shortest_distance(Aut aut, state_t_of< Aut > s0)
Single source shortest distance.
Definition: distance.hh:23
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
Definition: traits.hh:36
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:37
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
std::unordered_map< state_t_of< Aut >, std::pair< unsigned, transition_t_of< Aut > > > paths_ibfs(const Aut &aut, std::vector< state_t_of< Aut >> start)
Definition: distance.hh:74
variadic_mul_mixin< detail::r_impl > r
Definition: fwd.hh:42
bool has(const std::map< Key, Value, Compare, Alloc > &s, const Key &e)
Definition: map.hh:35