Cambridge SMT System
mapping-shortest-path.h
Go to the documentation of this file.
1 // shortest-path.h
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 // Author: allauzen@google.com (Cyril Allauzen)
16 //
17 // \file
18 // Functions to find shortest paths in an FST.
19 //
20 // This file has been modified by Aurelien Waite from the University of
21 // Cambridge.
22 //
23 // We found that mapping a lattice from tropical monomial weights to
24 // tropical weights was very expensive. This version of shortest path
25 // maps the weights on the fly with a value of gamma.
26 
27 #ifndef MERT_FST_LIB_SHORTEST_PATH_H__
28 #define MERT_FST_LIB_SHORTEST_PATH_H__
29 
30 #include <functional>
31 #include <utility>
32 #include <vector>
33 
34 #include <fst/cache.h>
35 #include <fst/determinize.h>
36 #include <fst/queue.h>
37 #include <fst/shortest-distance.h>
38 #include <fst/test-properties.h>
39 
40 namespace mertfst {
41 
42 // Shortest-path algorithm: normally not called directly; prefer
43 // 'ShortestPath' below with n=1. 'ofst' contains the shortest path in
44 // 'ifst'. 'distance' returns the shortest distances from the source
45 // state to each state in 'ifst'. 'opts' is used to specify options
46 // such as the queue discipline, the arc filter and delta.
47 //
48 // The shortest path is the lowest weight path w.r.t. the natural
49 // semiring order.
50 //
51 // The weights need to be right distributive and have the path (kPath)
52 // property.
53 template<class FArc, class TArc>
54 void SingleShortestPath (const fst::Fst<FArc>& ifst,
55  fst::MutableFst<TArc> *ofst, F gamma) {
56  typedef typename FArc::StateId StateId;
57  typedef typename FArc::Weight FWeight;
58  typedef typename TArc::Weight Weight;
59  std::vector<Weight> distance;
60  fst::AnyArcFilter < TArc > arc_filter;
61  fst::AutoQueue<typename FArc::StateId> state_queue (*ofst, &distance,
62  arc_filter);
63  ofst->DeleteStates();
64  ofst->SetInputSymbols (ifst.InputSymbols() );
65  ofst->SetOutputSymbols (ifst.OutputSymbols() );
66  if (ifst.Start() == fst::kNoStateId)
67  return;
68  std::vector<Weight> rdistance;
69  std::vector<bool> enqueued;
70  std::vector<StateId> parent;
71  std::vector<TArc> arc_parent;
72  //Queue *state_queue = opts.state_queue;
73  StateId source = ifst.Start();
74  Weight f_distance = Weight::Zero();
75  StateId f_parent = fst::kNoStateId;
76  distance.clear();
77  state_queue.Clear();
78  while (distance.size() < source) {
79  distance.push_back (Weight::Zero() );
80  enqueued.push_back (false);
81  parent.push_back (fst::kNoStateId);
82  arc_parent.push_back (TArc (fst::kNoLabel, fst::kNoLabel, Weight::Zero(),
83  fst::kNoStateId) );
84  }
85  distance.push_back (Weight::One() );
86  parent.push_back (fst::kNoStateId);
87  arc_parent.push_back (TArc (fst::kNoLabel, fst::kNoLabel, Weight::Zero(),
88  fst::kNoStateId) );
89  state_queue.Enqueue (source);
90  enqueued.push_back (true);
91  while (!state_queue.Empty() ) {
92  StateId s = state_queue.Head();
93  state_queue.Dequeue();
94  enqueued[s] = false;
95  Weight sd = distance[s];
96  if (ifst.Final (s) != FWeight::Zero() ) {
97  Weight w = Times (sd, ifst.Final (s).Map (gamma) );
98  if (f_distance != Plus (f_distance, w) ) {
99  f_distance = Plus (f_distance, w);
100  f_parent = s;
101  }
102  }
103  for (fst::ArcIterator < fst::Fst<FArc> > aiter (ifst, s); !aiter.Done();
104  aiter.Next() ) {
105  const FArc& arc = aiter.Value();
106  while (distance.size() <= arc.nextstate) {
107  distance.push_back (Weight::Zero() );
108  enqueued.push_back (false);
109  parent.push_back (fst::kNoStateId);
110  arc_parent.push_back (TArc (fst::kNoLabel, fst::kNoLabel, Weight::Zero(),
111  fst::kNoStateId) );
112  }
113  Weight& nd = distance[arc.nextstate];
114  Weight mw = arc.weight.Map (gamma);
115  Weight w = Times (sd, mw);
116  if (nd != Plus (nd, w) ) {
117  nd = Plus (nd, w);
118  parent[arc.nextstate] = s;
119  TArc tarc (arc.ilabel, arc.olabel, mw, arc.nextstate);
120  arc_parent[arc.nextstate] = tarc;
121  if (!enqueued[arc.nextstate]) {
122  state_queue.Enqueue (tarc.nextstate);
123  enqueued[arc.nextstate] = true;
124  } else {
125  state_queue.Update (tarc.nextstate);
126  }
127  }
128  }
129  }
130  distance[source] = Weight::One();
131  parent[source] = fst::kNoStateId;
132  StateId s_p = fst::kNoStateId, d_p = fst::kNoStateId;
133  for (StateId s = f_parent, d = fst::kNoStateId; s != fst::kNoStateId; d = s, s
134  = parent[s]) {
135  d_p = s_p;
136  s_p = ofst->AddState();
137  if (d == fst::kNoStateId) {
138  ofst->SetFinal (s_p, ifst.Final (f_parent).Map (gamma) );
139  } else {
140  arc_parent[d].nextstate = d_p;
141  ofst->AddArc (s_p, arc_parent[d]);
142  }
143  }
144  ofst->SetStart (s_p);
145 }
146 
147 } // namespace mertfst
148 
149 #endif // MERT_FST_LIB_SHORTEST_PATH_H__
void SingleShortestPath(const fst::Fst< FArc > &ifst, fst::MutableFst< TArc > *ofst, F gamma)
double F
TropicalSparseTupleWeight< T > Plus(const TropicalSparseTupleWeight< T > &vw1, const TropicalSparseTupleWeight< T > &vw2)
TropicalSparseTupleWeight< T > Times(const TropicalSparseTupleWeight< T > &w1, const TropicalSparseTupleWeight< T > &w2)