예제 #1
0
        /**
         * /// 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);
        }
예제 #2
0
        /**
         * /// 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);
        }