Beispiel #1
0
        /**
         * Find the best paths with cost at most OPT + costSlack, where OPT is the optimal solution. At most maxCount paths will be returned. The paths are ordered by cost in ascending order.
         *
         * @param lattice  the result of a build method
         * @param maxCount  the maximum number of paths to find
         * @param costSlack  the maximum cost slack of a path
         * @return  MultiSearchResult containing the shortest paths and their costs
         */
        public MultiSearchResult SearchMultiple(ViterbiLattice lattice, int maxCount, int costSlack)
        {
            CalculatePathCosts(lattice);
            MultiSearchResult result = multiSearcher.GetShortestPaths(lattice, maxCount, costSlack);

            return(result);
        }
Beispiel #2
0
        private List <MergeBuilder> MergeStep(List <MergeBuilder> builders, List <MultiSearchResult> results, int currentIndex)
        {
            MultiSearchResult         nextResult = results[currentIndex];
            PriorityQueue <MergePair> pairHeap   = new PriorityQueue <MergePair>();
            List <MergeBuilder>       ret        = new List <MultiSearchMerger.MergeBuilder>();

            if ((builders.Count == 0) || (nextResult.Count == 0))
            {
                return(ret);
            }

            pairHeap.Add(new MergePair(0, 0, builders[0].Cost + nextResult.GetCost(0)));

            HashSet <int> visited = new HashSet <int>();

            while (ret.Count < maxCount && pairHeap.Count > 0)
            {
                MergePair top = pairHeap.Poll();

                if (GetCostLowerBound(top.Cost, currentIndex) - baseCost > costSlack)
                {
                    break;
                }

                int i = top.LeftIndex;
                int j = top.RightIndex;

                MergeBuilder nextBuilder = new MergeBuilder(results, builders[i].Indices);
                nextBuilder.Add(j);
                ret.Add(nextBuilder);

                if (i + 1 < builders.Count)
                {
                    MergePair newMergePair  = new MergePair(i + 1, j, builders[i + 1].Cost + nextResult.GetCost(j));
                    int       positionValue = GetPositionValue(i + 1, j);
                    if (!visited.Contains(positionValue))
                    {
                        pairHeap.Add(newMergePair);
                        visited.Add(positionValue);
                    }
                }
                if (j + 1 < nextResult.Count)
                {
                    MergePair newMergePair  = new MergePair(i, j + 1, builders[i].Cost + nextResult.GetCost(j + 1));
                    int       positionValue = GetPositionValue(i, j + 1);
                    if (!visited.Contains(positionValue))
                    {
                        pairHeap.Add(newMergePair);
                        visited.Add(positionValue);
                    }
                }
            }

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

            suffixCostLowerBounds = new List <int>();
            for (int i = 0; i < results.Count; i++)
            {
                suffixCostLowerBounds.Add(0);
            }
            suffixCostLowerBounds[suffixCostLowerBounds.Count - 1] = results[results.Count - 1].GetCost(0);
            for (int i = results.Count - 2; i >= 0; i--)
            {
                suffixCostLowerBounds[i] = results[i].GetCost(0) + suffixCostLowerBounds[i + 1];
            }
            baseCost = suffixCostLowerBounds[0];

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

            for (int i = 0; i < results[0].Count; i++)
            {
                if (GetCostLowerBound(results[0].GetCost(i), 0) - baseCost > costSlack || i == maxCount)
                {
                    break;
                }

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

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

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

            return(ret);
        }
        /**
         * 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.
         *
         * @param lattice  an instance of ViterbiLattice prosecced by a ViterbiSearcher
         * @param maxCount  the maximum number of results
         * @param costSlack  the maximum cost slack of a path
         * @return  the shortest paths and their costs
         */
        public MultiSearchResult GetShortestPaths(ViterbiLattice lattice, int maxCount, int costSlack)
        {
            pathCosts  = new List <int>();
            sidetracks = new Dictionary <ViterbiNode, MultiSearcher.SidetrackEdge>();
            MultiSearchResult multiSearchResult = new MultiSearchResult();

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

            baseCost = eos.PathCost;
            List <SidetrackEdge> paths = GetPaths(eos, maxCount, costSlack);
            int i = 0;

            foreach (SidetrackEdge path in paths)
            {
                LinkedList <ViterbiNode> nodes = GeneratePath(eos, path);
                multiSearchResult.Add(nodes, pathCosts[i]);
                i += 1;
            }
            return(multiSearchResult);
        }