Example #1
0
        public MultiSearchResult Merge(List <MultiSearchResult> results)
        {
            if (results.Count == 0)
            {
                return(new MultiSearchResult());
            }

            SuffixCostLowerBounds.Clear();
            SuffixCostLowerBounds.AddRange(Enumerable.Repeat(0, results.Count));
            SuffixCostLowerBounds[SuffixCostLowerBounds.Count - 1] = results[results.Count - 1].GetCost(0);
            for (var i = results.Count - 2; i >= 0; i--)
            {
                SuffixCostLowerBounds[i] = results[i].GetCost(0) + SuffixCostLowerBounds[i + 1];
            }
            BaseCost = SuffixCostLowerBounds[0];

            var ret      = new MultiSearchResult();
            var builders = new List <MergeBuilder>();

            for (var i = 0; i < results[0].Count; i++)
            {
                if (GetCostLowerBound(results[0].GetCost(i), 0) - BaseCost > CostSlack || i == MaxCount)
                {
                    break;
                }

                var newBuilder = new MergeBuilder(results);
                newBuilder.Add(i);
                builders.Add(newBuilder);
            }

            for (var i = 1; i < results.Count; i++)
            {
                builders = MergeStep(builders, results, i);
            }

            foreach (var builder in builders)
            {
                ret.Add(builder.BuildList(), builder.Cost);
            }

            return(ret);
        }
Example #2
0
        /// <summary>
        /// Get up to maxCount shortest paths with cost at most OPT + costSlack, where OPT is the optimal solution. The results are ordered in ascending order by cost.
        /// </summary>
        /// <param name="lattice">an instance of ViterbiLattice prosecced by a ViterbiSearcher</param>
        /// <param name="maxCount">the maximum number of results</param>
        /// <param name="costSlack">the maximum cost slack of a path</param>
        /// <returns>the shortest paths and their costs</returns>
        public MultiSearchResult GetShortestPaths(ViterbiLattice lattice, int maxCount, int costSlack)
        {
            PathCosts.Clear();
            Sidetracks.Clear();
            var multiSearchResult = new MultiSearchResult();

            BuildSidetracks(lattice);
            var eos = lattice.EndIndexArr[0][0];

            BaseCost = eos.PathCost;
            var paths = GetPaths(eos, maxCount, costSlack);

            foreach (var(path, cost) in paths.Zip(Enumerable.Range(0, paths.Count), (p, i) => Tuple.Create(p, PathCosts[i])))
            {
                var nodes = GeneratePath(eos, path);
                multiSearchResult.Add(nodes, cost);
            }

            return(multiSearchResult);
        }