/** * /// Reverses an fst * /// * /// @param fst the fst to reverse * /// @return the reversed fst */ public static Fst Get(Fst fst) { if (fst.Semiring == null) { return(null); } ExtendFinal.Apply(fst); Semiring semiring = fst.Semiring; Fst res = new Fst(fst.GetNumStates()); res.Semiring = semiring; res.Isyms = fst.Osyms; res.Osyms = fst.Isyms; State[] stateMap = new State[fst.GetNumStates()]; int numStates = fst.GetNumStates(); for (int i = 0; i < numStates; i++) { State _is = fst.GetState(i); State s = new State(semiring.Zero); res.AddState(s); stateMap[_is.GetId()] = s; if (_is.FinalWeight != semiring.Zero) { res.SetStart(s); } } stateMap[fst.Start.GetId()].FinalWeight = semiring.One; for (int i = 0; i < numStates; i++) { State olds = fst.GetState(i); State news = stateMap[olds.GetId()]; int numArcs = olds.GetNumArcs(); for (int j = 0; j < numArcs; j++) { Arc olda = olds.GetArc(j); State next = stateMap[olda.NextState.GetId()]; Arc newa = new Arc(olda.Ilabel, olda.Olabel, semiring.Reverse(olda.Weight), news); next.AddArc(newa); } } ExtendFinal.Undo(fst); return(res); }
/** * /// Calculates the n-best shortest path from the initial to the final state. * /// * /// @param fst * /// the fst to calculate the nbest shortest paths * /// @param n * /// number of best paths to return * /// @param determinize * /// if true the input fst will bwe determinized prior the * /// operation * /// @return an fst containing the n-best shortest paths */ public static Fst Get(Fst fst, int n, Boolean determinize) { if (fst == null) { return(null); } if (fst.Semiring == null) { return(null); } var fstdet = fst; if (determinize) { fstdet = Determinize.Get(fst); } var semiring = fstdet.Semiring; var res = new Fst(semiring); res.Isyms = fstdet.Isyms; res.Osyms = fstdet.Osyms; var d = ShortestDistance(fstdet); ExtendFinal.Apply(fstdet); var r = new int[fstdet.GetNumStates()]; var queue = new PriorityQueue <Pair <State, float> >(new CustomComparer(d, semiring)); var previous = new HashMap <Pair <State, float>, Pair <State, float> >(fst.GetNumStates()); var stateMap = new HashMap <Pair <State, float>, State>(fst.GetNumStates()); var start = fstdet.Start; var item = new Pair <State, float>(start, semiring.One); queue.Add(item); previous.Put(item, null); while (queue.Count != 0) { var pair = queue.Remove(); var p = pair.GetLeft(); var c = pair.GetRight(); var s = new State(p.FinalWeight); res.AddState(s); stateMap.Put(pair, s); if (previous[pair] == null) { // this is the start state res.SetStart(s); } else { // add the incoming arc from previous to current var previouState = stateMap.Get(previous.Get(pair)); var previousOldState = previous.Get(pair).GetLeft(); for (var j = 0; j < previousOldState.GetNumArcs(); j++) { var a = previousOldState.GetArc(j); if (a.NextState.Equals(p)) { previouState.AddArc(new Arc(a.Ilabel, a.Olabel, a.Weight, s)); } } } var stateIndex = p.GetId(); r[stateIndex]++; if ((r[stateIndex] == n) && (p.FinalWeight != semiring.Zero)) { break; } if (r[stateIndex] <= n) { for (var j = 0; j < p.GetNumArcs(); j++) { var a = p.GetArc(j); var cnew = semiring.Times(c, a.Weight); var next = new Pair <State, float>(a.NextState, cnew); previous.Put(next, pair); queue.Add(next); } } } return(res); }