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); }
List <MergeBuilder> MergeStep(List <MergeBuilder> builders, List <MultiSearchResult> results, int currentIndex) { var nextResult = results[currentIndex]; var pairHeap = new PriorityQueue <MergePair>(); var ret = new List <MergeBuilder>(); if (builders.Count == 0 || nextResult.Count == 0) { return(ret); } pairHeap.Enqueue(new MergePair(0, 0, builders[0].Cost + nextResult.GetCost(0))); var visited = new HashSet <int>(); while (ret.Count < MaxCount && pairHeap.Count > 0) { var top = pairHeap.Dequeue(); if (GetCostLowerBound(top.Cost, currentIndex) - BaseCost > CostSlack) { break; } var i = top.LeftIndex; var j = top.RightIndex; var nextBuilder = new MergeBuilder(results, builders[i].Indices); nextBuilder.Add(j); ret.Add(nextBuilder); if (i + 1 < builders.Count) { var newMergePair = new MergePair(i + 1, j, builders[i + 1].Cost + nextResult.GetCost(j)); var positionValue = GetPositionValue(i + 1, j); if (!visited.Contains(positionValue)) { pairHeap.Add(newMergePair); visited.Add(positionValue); } } if (j + 1 < nextResult.Count) { var newMergePair = new MergePair(i, j + 1, builders[i].Cost + nextResult.GetCost(j + 1)); var positionValue = GetPositionValue(i, j + 1); if (!visited.Contains(positionValue)) { pairHeap.Add(newMergePair); visited.Add(positionValue); } } } return(ret); }
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); }
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); }