FST  openfst-1.8.3
OpenFst Library
shortest-path.h
Go to the documentation of this file.
1 // Copyright 2005-2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the 'License');
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an 'AS IS' BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // See www.openfst.org for extensive documentation on this weighted
16 // finite-state transducer library.
17 //
18 // Functions to find shortest paths in an FST.
19 
20 #ifndef FST_SHORTEST_PATH_H_
21 #define FST_SHORTEST_PATH_H_
22 
23 #include <algorithm>
24 #include <cstddef>
25 #include <cstdint>
26 #include <functional>
27 #include <type_traits>
28 #include <utility>
29 #include <vector>
30 
31 #include <fst/log.h>
32 #include <fst/arc.h>
33 #include <fst/arcfilter.h>
34 #include <fst/cache.h>
35 #include <fst/connect.h>
36 #include <fst/determinize.h>
37 #include <fst/fst.h>
38 #include <fst/mutable-fst.h>
39 #include <fst/properties.h>
40 #include <fst/queue.h>
41 #include <fst/reverse.h>
42 #include <fst/shortest-distance.h>
43 #include <fst/vector-fst.h>
44 #include <fst/weight.h>
45 
46 namespace fst {
47 
48 template <class Arc, class Queue, class ArcFilter>
50  : public ShortestDistanceOptions<Arc, Queue, ArcFilter> {
51  using StateId = typename Arc::StateId;
52  using Weight = typename Arc::Weight;
53 
54  int32_t nshortest; // Returns n-shortest paths.
55  bool unique; // Only returns paths with distinct input strings.
56  bool has_distance; // Distance vector already contains the
57  // shortest distance from the initial state.
58  bool first_path; // Single shortest path stops after finding the first
59  // path to a final state; that path is the shortest path
60  // only when:
61  // (1) using the ShortestFirstQueue with all the weights
62  // in the FST being between One() and Zero() according to
63  // NaturalLess or when
64  // (2) using the NaturalAStarQueue with an admissible
65  // and consistent estimate.
66  Weight weight_threshold; // Pruning weight threshold.
67  StateId state_threshold; // Pruning state threshold.
68 
69  ShortestPathOptions(Queue *queue, ArcFilter filter, int32_t nshortest = 1,
70  bool unique = false, bool has_distance = false,
71  float delta = kShortestDelta, bool first_path = false,
72  Weight weight_threshold = Weight::Zero(),
73  StateId state_threshold = kNoStateId)
74  : ShortestDistanceOptions<Arc, Queue, ArcFilter>(queue, filter,
75  kNoStateId, delta),
76  nshortest(nshortest),
77  unique(unique),
78  has_distance(has_distance),
79  first_path(first_path),
80  weight_threshold(std::move(weight_threshold)),
81  state_threshold(state_threshold) {}
82 };
83 
84 namespace internal {
85 
86 inline constexpr size_t kNoArc = -1;
87 
88 // Helper function for SingleShortestPath building the shortest path as a left-
89 // to-right machine backwards from the best final state. It takes the input
90 // FST passed to SingleShortestPath and the parent vector and f_parent returned
91 // by that function, and builds the result into the provided output mutable FS
92 // This is not normally called by users; see ShortestPath instead.
93 template <class Arc>
95  const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
96  const std::vector<std::pair<typename Arc::StateId, size_t>> &parent,
97  typename Arc::StateId f_parent) {
98  using StateId = typename Arc::StateId;
99  ofst->DeleteStates();
100  ofst->SetInputSymbols(ifst.InputSymbols());
101  ofst->SetOutputSymbols(ifst.OutputSymbols());
102  StateId s_p = kNoStateId;
103  StateId d_p = kNoStateId;
104  for (StateId state = f_parent, d = kNoStateId; state != kNoStateId;
105  d = state, state = parent[state].first) {
106  d_p = s_p;
107  s_p = ofst->AddState();
108  if (d == kNoStateId) {
109  ofst->SetFinal(s_p, ifst.Final(f_parent));
110  } else {
111  ArcIterator<Fst<Arc>> aiter(ifst, state);
112  aiter.Seek(parent[d].second);
113  auto arc = aiter.Value();
114  arc.nextstate = d_p;
115  ofst->AddArc(s_p, std::move(arc));
116  }
117  }
118  ofst->SetStart(s_p);
119  if (ifst.Properties(kError, false)) ofst->SetProperties(kError, kError);
120  ofst->SetProperties(
121  ShortestPathProperties(ofst->Properties(kFstProperties, false), true),
123 }
124 
125 // Implements the stopping criterion when ShortestPathOptions::first_path
126 // is set to true:
127 // operator()(s, d, f) == true
128 // iff every successful path through state 's' has a cost greater or equal
129 // to 'f' under the assumption that 'd' is the shortest distance to state 's'.
130 // Correct when using the ShortestFirstQueue with all the weights in the FST
131 // being between One() and Zero() according to NaturalLess
132 template <typename S, typename W, typename Queue>
134  FirstPathSelect(const Queue &) {}
135  bool operator()(S s, W d, W f) const { return f == Plus(d, f); }
136 };
137 
138 // Specialisation for A*.
139 // Correct when the estimate is admissible and consistent.
140 template <typename S, typename W, typename Estimate>
141 class FirstPathSelect<S, W, NaturalAStarQueue<S, W, Estimate>> {
142  public:
144 
146  : estimate_(state_queue.GetCompare().GetEstimate()) {}
147 
148  bool operator()(S s, W d, W f) const {
149  return f == Plus(Times(d, estimate_(s)), f);
150  }
151 
152  private:
153  const Estimate &estimate_;
154 };
155 
156 // Shortest-path algorithm. It builds the output mutable FST so that it contains
157 // the shortest path in the input FST; distance returns the shortest distances
158 // from the source state to each state in the input FST, and the options struct
159 // is
160 // used to specify options such as the queue discipline, the arc filter and
161 // delta. The super_final option is an output parameter indicating the final
162 // state, and the parent argument is used for the storage of the backtrace path
163 // for each state 1 to n, (i.e., the best previous state and the arc that
164 // transition to state n.) The shortest path is the lowest weight path w.r.t.
165 // the natural semiring order. The weights need to be right distributive and
166 // have the path (kPath) property. False is returned if an error is encountered.
167 //
168 // This is not normally called by users; see ShortestPath instead (with n = 1).
169 template <class Arc, class Queue, class ArcFilter>
171  const Fst<Arc> &ifst, std::vector<typename Arc::Weight> *distance,
173  typename Arc::StateId *f_parent,
174  std::vector<std::pair<typename Arc::StateId, size_t>> *parent) {
175  using StateId = typename Arc::StateId;
176  using Weight = typename Arc::Weight;
177  static_assert(IsPath<Weight>::value, "Weight must have path property.");
178  static_assert((Weight::Properties() & kRightSemiring) == kRightSemiring,
179  "Weight must be right distributive.");
180  parent->clear();
181  *f_parent = kNoStateId;
182  if (ifst.Start() == kNoStateId) return true;
183  std::vector<bool> enqueued;
184  auto state_queue = opts.state_queue;
185  const auto source = (opts.source == kNoStateId) ? ifst.Start() : opts.source;
186  bool final_seen = false;
187  auto f_distance = Weight::Zero();
188  distance->clear();
189  state_queue->Clear();
190  while (distance->size() < source) {
191  distance->push_back(Weight::Zero());
192  enqueued.push_back(false);
193  parent->emplace_back(kNoStateId, kNoArc);
194  }
195  distance->push_back(Weight::One());
196  parent->emplace_back(kNoStateId, kNoArc);
197  state_queue->Enqueue(source);
198  enqueued.push_back(true);
199  while (!state_queue->Empty()) {
200  const auto s = state_queue->Head();
201  state_queue->Dequeue();
202  enqueued[s] = false;
203  const auto sd = (*distance)[s];
204  // If we are using a shortest queue, no other path is going to be shorter
205  // than f_distance at this point.
206  using FirstPath = FirstPathSelect<StateId, Weight, Queue>;
207  if (opts.first_path && final_seen &&
208  FirstPath(*state_queue)(s, sd, f_distance)) {
209  break;
210  }
211  if (ifst.Final(s) != Weight::Zero()) {
212  const auto plus = Plus(f_distance, Times(sd, ifst.Final(s)));
213  if (f_distance != plus) {
214  f_distance = plus;
215  *f_parent = s;
216  }
217  if (!f_distance.Member()) return false;
218  final_seen = true;
219  }
220  for (ArcIterator<Fst<Arc>> aiter(ifst, s); !aiter.Done(); aiter.Next()) {
221  const auto &arc = aiter.Value();
222  while (distance->size() <= arc.nextstate) {
223  distance->push_back(Weight::Zero());
224  enqueued.push_back(false);
225  parent->emplace_back(kNoStateId, kNoArc);
226  }
227  auto &nd = (*distance)[arc.nextstate];
228  const auto weight = Times(sd, arc.weight);
229  if (nd != Plus(nd, weight)) {
230  nd = Plus(nd, weight);
231  if (!nd.Member()) return false;
232  (*parent)[arc.nextstate] = std::make_pair(s, aiter.Position());
233  if (!enqueued[arc.nextstate]) {
234  state_queue->Enqueue(arc.nextstate);
235  enqueued[arc.nextstate] = true;
236  } else {
237  state_queue->Update(arc.nextstate);
238  }
239  }
240  }
241  }
242  return true;
243 }
244 
245 template <class StateId, class Weight>
247  public:
248  ShortestPathCompare(const std::vector<std::pair<StateId, Weight>> &pairs,
249  const std::vector<Weight> &distance, StateId superfinal,
250  float delta)
251  : pairs_(pairs),
252  distance_(distance),
253  superfinal_(superfinal),
254  delta_(delta) {}
255 
256  bool operator()(const StateId x, const StateId y) const {
257  const auto &px = pairs_[x];
258  const auto &py = pairs_[y];
259  const auto wx = Times(PWeight(px.first), px.second);
260  const auto wy = Times(PWeight(py.first), py.second);
261  // Penalize complete paths to ensure correct results with inexact weights.
262  // This forms a strict weak order so long as ApproxEqual(a, b) =>
263  // ApproxEqual(a, c) for all c s.t. less_(a, c) && less_(c, b).
264  if (px.first == superfinal_ && py.first != superfinal_) {
265  return less_(wy, wx) || ApproxEqual(wx, wy, delta_);
266  } else if (py.first == superfinal_ && px.first != superfinal_) {
267  return less_(wy, wx) && !ApproxEqual(wx, wy, delta_);
268  } else {
269  return less_(wy, wx);
270  }
271  }
272 
273  private:
274  Weight PWeight(StateId state) const {
275  return (state == superfinal_) ? Weight::One()
276  : (state < distance_.size()) ? distance_[state]
277  : Weight::Zero();
278  }
279 
280  const std::vector<std::pair<StateId, Weight>> &pairs_;
281  const std::vector<Weight> &distance_;
282  const StateId superfinal_;
283  const float delta_;
284  NaturalLess<Weight> less_;
285 };
286 
287 // N-Shortest-path algorithm: implements the core n-shortest path algorithm.
288 // The output is built reversed. See below for versions with more options and
289 // *not reversed*.
290 //
291 // The output mutable FST contains the REVERSE of n'shortest paths in the input
292 // FST; distance must contain the shortest distance from each state to a final
293 // state in the input FST; delta is the convergence delta.
294 //
295 // The n-shortest paths are the n-lowest weight paths w.r.t. the natural
296 // semiring order. The single path that can be read from the ith of at most n
297 // transitions leaving the initial state of the input FST is the ith shortest
298 // path. Disregarding the initial state and initial transitions, the
299 // n-shortest paths, in fact, form a tree rooted at the single final state.
300 //
301 // The weights need to be left and right distributive (kSemiring) and have the
302 // path (kPath) property.
303 //
304 // Arc weights must satisfy the property that the sum of the weights of one or
305 // more paths from some state S to T is never Zero(). In particular, arc weights
306 // are never Zero().
307 //
308 // For more information, see:
309 //
310 // Mohri, M, and Riley, M. 2002. An efficient algorithm for the n-best-strings
311 // problem. In Proc. ICSLP.
312 //
313 // The algorithm relies on the shortest-distance algorithm. There are some
314 // issues with the pseudo-code as written in the paper (viz., line 11).
315 //
316 // IMPLEMENTATION NOTE: The input FST can be a delayed FST and at any state in
317 // its expansion the values of distance vector need only be defined at that time
318 // for the states that are known to exist.
319 template <class Arc, class RevArc>
320 void NShortestPath(const Fst<RevArc> &ifst, MutableFst<Arc> *ofst,
321  const std::vector<typename Arc::Weight> &distance,
322  int32_t nshortest, float delta = kShortestDelta,
323  typename Arc::Weight weight_threshold = Arc::Weight::Zero(),
324  typename Arc::StateId state_threshold = kNoStateId) {
325  using StateId = typename Arc::StateId;
326  using Weight = typename Arc::Weight;
327  using Pair = std::pair<StateId, Weight>;
328  static_assert((Weight::Properties() & kPath) == kPath,
329  "Weight must have path property.");
330  static_assert((Weight::Properties() & kSemiring) == kSemiring,
331  "Weight must be distributive.");
332  if (nshortest <= 0) return;
333  ofst->DeleteStates();
334  ofst->SetInputSymbols(ifst.InputSymbols());
335  ofst->SetOutputSymbols(ifst.OutputSymbols());
336  // Each state in ofst corresponds to a path with weight w from the initial
337  // state of ifst to a state s in ifst, that can be characterized by a pair
338  // (s, w). The vector pairs maps each state in ofst to the corresponding
339  // pair maps states in ofst to the corresponding pair (s, w).
340  std::vector<Pair> pairs;
341  // The superfinal state is denoted by kNoStateId. The distance from the
342  // superfinal state to the final state is semiring One, so
343  // `distance[kNoStateId]` is not needed.
344  const ShortestPathCompare<StateId, Weight> compare(pairs, distance,
345  kNoStateId, delta);
346  const NaturalLess<Weight> less;
347  if (ifst.Start() == kNoStateId || distance.size() <= ifst.Start() ||
348  distance[ifst.Start()] == Weight::Zero() ||
349  less(weight_threshold, Weight::One()) || state_threshold == 0) {
350  if (ifst.Properties(kError, false)) ofst->SetProperties(kError, kError);
351  return;
352  }
353  ofst->SetStart(ofst->AddState());
354  const auto final_state = ofst->AddState();
355  ofst->SetFinal(final_state);
356  while (pairs.size() <= final_state) {
357  pairs.emplace_back(kNoStateId, Weight::Zero());
358  }
359  pairs[final_state] = std::make_pair(ifst.Start(), Weight::One());
360  std::vector<StateId> heap;
361  heap.push_back(final_state);
362  const auto limit = Times(distance[ifst.Start()], weight_threshold);
363  // r[s + 1], s state in fst, is the number of states in ofst which
364  // corresponding pair contains s, i.e., it is number of paths computed so far
365  // to s. Valid for s == kNoStateId (the superfinal state).
366  std::vector<int> r;
367  while (!heap.empty()) {
368  std::pop_heap(heap.begin(), heap.end(), compare);
369  const auto state = heap.back();
370  const auto p = pairs[state];
371  heap.pop_back();
372  const auto d = (p.first == kNoStateId) ? Weight::One()
373  : (p.first < distance.size()) ? distance[p.first]
374  : Weight::Zero();
375  if (less(limit, Times(d, p.second)) ||
376  (state_threshold != kNoStateId &&
377  ofst->NumStates() >= state_threshold)) {
378  continue;
379  }
380  while (r.size() <= p.first + 1) r.push_back(0);
381  ++r[p.first + 1];
382  if (p.first == kNoStateId) ofst->AddArc(ofst->Start(), Arc(0, 0, state));
383  if ((p.first == kNoStateId) && (r[p.first + 1] == nshortest)) break;
384  if (r[p.first + 1] > nshortest) continue;
385  if (p.first == kNoStateId) continue;
386  for (ArcIterator<Fst<RevArc>> aiter(ifst, p.first); !aiter.Done();
387  aiter.Next()) {
388  const auto &rarc = aiter.Value();
389  Arc arc(rarc.ilabel, rarc.olabel, rarc.weight.Reverse(), rarc.nextstate);
390  const auto weight = Times(p.second, arc.weight);
391  const auto next = ofst->AddState();
392  pairs.emplace_back(arc.nextstate, weight);
393  arc.nextstate = state;
394  ofst->AddArc(next, std::move(arc));
395  heap.push_back(next);
396  std::push_heap(heap.begin(), heap.end(), compare);
397  }
398  const auto final_weight = ifst.Final(p.first).Reverse();
399  if (final_weight != Weight::Zero()) {
400  const auto weight = Times(p.second, final_weight);
401  const auto next = ofst->AddState();
402  pairs.emplace_back(kNoStateId, weight);
403  ofst->AddArc(next, Arc(0, 0, final_weight, state));
404  heap.push_back(next);
405  std::push_heap(heap.begin(), heap.end(), compare);
406  }
407  }
408  Connect(ofst);
409  if (ifst.Properties(kError, false)) ofst->SetProperties(kError, kError);
410  ofst->SetProperties(
413 }
414 
415 } // namespace internal
416 
417 // N-Shortest-path algorithm: this version allows finer control via the options
418 // argument. See below for a simpler interface. The output mutable FST contains
419 // the n-shortest paths in the input FST; the distance argument is used to
420 // return the shortest distances from the source state to each state in the
421 // input FST, and the options struct is used to specify the number of paths to
422 // return, whether they need to have distinct input strings, the queue
423 // discipline, the arc filter and the convergence delta.
424 //
425 // The n-shortest paths are the n-lowest weight paths w.r.t. the natural
426 // semiring order. The single path that can be read from the ith of at most n
427 // transitions leaving the initial state of the output FST is the ith shortest
428 // path.
429 // Disregarding the initial state and initial transitions, The n-shortest paths,
430 // in fact, form a tree rooted at the single final state.
431 //
432 // The weights need to be right distributive and have the path (kPath) property.
433 // They need to be left distributive as well for nshortest > 1.
434 //
435 // For more information, see:
436 //
437 // Mohri, M, and Riley, M. 2002. An efficient algorithm for the n-best-strings
438 // problem. In Proc. ICSLP.
439 //
440 // The algorithm relies on the shortest-distance algorithm. There are some
441 // issues with the pseudo-code as written in the paper (viz., line 11).
442 template <class Arc, class Queue, class ArcFilter>
443 void ShortestPath(const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
444  std::vector<typename Arc::Weight> *distance,
446  using StateId = typename Arc::StateId;
447  using Weight = typename Arc::Weight;
448  using RevArc = ReverseArc<Arc>;
449  static_assert(IsPath<Weight>::value,
450  "ShortestPath: Weight needs to have the path property and "
451  "be distributive");
452 
453  if (opts.nshortest == 1) {
454  std::vector<std::pair<StateId, size_t>> parent;
455  StateId f_parent;
456  if (internal::SingleShortestPath(ifst, distance, opts, &f_parent,
457  &parent)) {
458  internal::SingleShortestPathBacktrace(ifst, ofst, parent, f_parent);
459  } else {
460  ofst->SetProperties(kError, kError);
461  }
462  return;
463  }
464  if (opts.nshortest <= 0) return;
465  if (!opts.has_distance) {
466  ShortestDistance(ifst, distance, opts);
467  if (distance->size() == 1 && !(*distance)[0].Member()) {
468  ofst->SetProperties(kError, kError);
469  return;
470  }
471  }
472  // Algorithm works on the reverse of 'fst'; 'distance' is the distance to the
473  // final state in 'rfst', 'ofst' is built as the reverse of the tree of
474  // n-shortest path in 'rfst'.
475  VectorFst<RevArc> rfst;
476  Reverse(ifst, &rfst);
477  auto d = Weight::Zero();
478  for (ArcIterator<VectorFst<RevArc>> aiter(rfst, 0); !aiter.Done();
479  aiter.Next()) {
480  const auto &arc = aiter.Value();
481  const auto state = arc.nextstate - 1;
482  if (state < distance->size()) {
483  d = Plus(d, Times(arc.weight.Reverse(), (*distance)[state]));
484  }
485  }
486  // TODO(kbg): Avoid this expensive vector operation.
487  distance->insert(distance->begin(), d);
488  if (!opts.unique) {
489  internal::NShortestPath(rfst, ofst, *distance, opts.nshortest, opts.delta,
490  opts.weight_threshold, opts.state_threshold);
491  } else {
492  std::vector<Weight> ddistance;
493  const DeterminizeFstOptions<RevArc> dopts(opts.delta);
494  const DeterminizeFst<RevArc> dfst(rfst, distance, &ddistance, dopts);
495  internal::NShortestPath(dfst, ofst, ddistance, opts.nshortest, opts.delta,
496  opts.weight_threshold, opts.state_threshold);
497  }
498  // TODO(kbg): Avoid this expensive vector operation.
499  distance->erase(distance->begin());
500 }
501 
502 // Shortest-path algorithm: simplified interface. See above for a version that
503 // allows finer control. The output mutable FST contains the n-shortest paths
504 // in the input FST. The queue discipline is automatically selected. When unique
505 // is true, only paths with distinct input label sequences are returned.
506 //
507 // The n-shortest paths are the n-lowest weight paths w.r.t. the natural
508 // semiring order. The single path that can be read from the ith of at most n
509 // transitions leaving the initial state of the output FST is the ith best path.
510 // The weights need to be right distributive and have the path (kPath) property.
511 template <class Arc>
512 void ShortestPath(const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
513  int32_t nshortest = 1, bool unique = false,
514  bool first_path = false,
515  typename Arc::Weight weight_threshold = Arc::Weight::Zero(),
516  typename Arc::StateId state_threshold = kNoStateId,
517  float delta = kShortestDelta) {
518  using StateId = typename Arc::StateId;
519  std::vector<typename Arc::Weight> distance;
521  AutoQueue<StateId> state_queue(ifst, &distance, arc_filter);
523  &state_queue, arc_filter, nshortest, unique, false, delta, first_path,
524  weight_threshold, state_threshold);
525  ShortestPath(ifst, ofst, &distance, opts);
526 }
527 
528 } // namespace fst
529 
530 #endif // FST_SHORTEST_PATH_H_
constexpr uint64_t kSemiring
Definition: weight.h:141
virtual uint64_t Properties(uint64_t mask, bool test) const =0
ErrorWeight Plus(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:61
uint64_t ShortestPathProperties(uint64_t props, bool tree=false)
Definition: properties.cc:373
ErrorWeight Times(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:64
constexpr uint64_t kError
Definition: properties.h:52
virtual void SetInputSymbols(const SymbolTable *isyms)=0
virtual Weight Final(StateId) const =0
virtual void SetStart(StateId)=0
void Connect(MutableFst< Arc > *fst)
Definition: connect.h:47
constexpr int kNoStateId
Definition: fst.h:196
const Arc & Value() const
Definition: fst.h:536
bool SingleShortestPath(const Fst< Arc > &ifst, std::vector< typename Arc::Weight > *distance, const ShortestPathOptions< Arc, Queue, ArcFilter > &opts, typename Arc::StateId *f_parent, std::vector< std::pair< typename Arc::StateId, size_t >> *parent)
void Reverse(const Fst< Arc > &ifst, const std::vector< std::pair< typename Arc::Label, typename Arc::Label >> &parens, std::vector< typename Arc::Label > *assignments, MutableFst< RevArc > *ofst)
Definition: reverse.h:36
constexpr uint64_t kRightSemiring
Definition: weight.h:139
void SingleShortestPathBacktrace(const Fst< Arc > &ifst, MutableFst< Arc > *ofst, const std::vector< std::pair< typename Arc::StateId, size_t >> &parent, typename Arc::StateId f_parent)
Definition: shortest-path.h:94
ShortestPathOptions(Queue *queue, ArcFilter filter, int32_t nshortest=1, bool unique=false, bool has_distance=false, float delta=kShortestDelta, bool first_path=false, Weight weight_threshold=Weight::Zero(), StateId state_threshold=kNoStateId)
Definition: shortest-path.h:69
typename Arc::StateId StateId
Definition: shortest-path.h:51
void Seek(size_t a)
Definition: fst.h:556
virtual void SetProperties(uint64_t props, uint64_t mask)=0
virtual StateId Start() const =0
constexpr float kShortestDelta
void NShortestPath(const Fst< RevArc > &ifst, MutableFst< Arc > *ofst, const std::vector< typename Arc::Weight > &distance, int32_t nshortest, float delta=kShortestDelta, typename Arc::Weight weight_threshold=Arc::Weight::Zero(), typename Arc::StateId state_threshold=kNoStateId)
void ShortestPath(const Fst< Arc > &ifst, const std::vector< std::pair< typename Arc::Label, typename Arc::Label >> &parens, MutableFst< Arc > *ofst, const PdtShortestPathOptions< Arc, Queue > &opts)
constexpr size_t kNoArc
Definition: shortest-path.h:86
constexpr uint64_t kPath
Definition: weight.h:150
typename Arc::StateId StateId
constexpr uint64_t kFstProperties
Definition: properties.h:326
virtual void AddArc(StateId, const Arc &)=0
bool operator()(S s, W d, W f) const
virtual const SymbolTable * InputSymbols() const =0
virtual StateId AddState()=0
virtual void SetFinal(StateId s, Weight weight=Weight::One())=0
virtual void DeleteStates(const std::vector< StateId > &)=0
void ShortestDistance(const Fst< Arc > &fst, std::vector< typename Arc::Weight > *distance, const ShortestDistanceOptions< Arc, Queue, ArcFilter > &opts)
bool operator()(const StateId x, const StateId y) const
virtual void SetOutputSymbols(const SymbolTable *osyms)=0
virtual StateId NumStates() const =0
ShortestPathCompare(const std::vector< std::pair< StateId, Weight >> &pairs, const std::vector< Weight > &distance, StateId superfinal, float delta)
typename Arc::Weight Weight
Definition: shortest-path.h:52
std::bool_constant<(W::Properties()&kPath)!=0 > IsPath
Definition: weight.h:162
bool ApproxEqual(const ErrorWeight &, const ErrorWeight &, float)
Definition: error-weight.h:58
virtual const SymbolTable * OutputSymbols() const =0