/// <summary> /// Returns the line from "matching lines" that has the least overlapping rating with "lineInfo". /// </summary> private static ExtendedLineInfo GetLeastFittingLine(LineInfo lineInfo, LinkedList <ExtendedLineInfo> matchingLines) { double leastFittingOverlappingScore = 0.5; ExtendedLineInfo leastFittingLine = null; foreach (ExtendedLineInfo matchingLine in matchingLines) { double currentOverlappingScore = UtilsCommon.OverlappingScore(lineInfo, matchingLine); if (leastFittingLine == null || (currentOverlappingScore < leastFittingOverlappingScore)) { leastFittingOverlappingScore = currentOverlappingScore; leastFittingLine = matchingLine; } } return(leastFittingLine); }
/// <summary> /// Returns the longest list of line containers, for which no line containers overlap. Addtionaly /// these containers are sorted by start time. /// </summary> public static List <LineContainer <T> > GetNonOverlappingTimeSpans <T>(LinkedList <T> lines, double threshold = 0) where T : ITimeSpan { var containers = new LinkedList <LineContainer <T> >(); var lineAlreadyAdded = new bool[lines.Count]; var lineANode = lines.First; var lineBNode = lines.First; int lineAindex = 0; int lineBindex = 0; while (lineANode != null) { if (lineAlreadyAdded [lineAindex]) { lineAindex++; lineANode = lineANode.Next; continue; } // create new container for this line var lineContainer = new LineContainer <T>(); lineContainer.AddLine(lineANode.Value); lineAlreadyAdded[lineAindex] = true; containers.AddLast(lineContainer); restartLoop: lineBNode = lineANode.Next; lineBindex = lineAindex + 1; while (lineBNode != null) { if (lineAlreadyAdded [lineBindex]) { lineBindex++; lineBNode = lineBNode.Next; continue; } // just test treshold if line collides with container if (UtilsCommon.IsOverlapping(lineBNode.Value, lineContainer)) { foreach (ITimeSpan timeSpanInContainer in lineContainer.TimeSpans) { if (UtilsCommon.OverlappingScore(lineBNode.Value, timeSpanInContainer) > threshold) { lineContainer.AddLine(lineBNode.Value); lineAlreadyAdded[lineBindex] = true; goto restartLoop; } } } lineBindex++; lineBNode = lineBNode.Next; } lineAindex++; lineANode = lineANode.Next; } // XXX: is sort necessary var containerList = containers.ToList(); containerList.Sort(); return(containerList); }
/// <summary> /// This creates a list of good matching lines between primaryList and secondaryList. /// </summary> /// <param name="list1">List1.</param> /// <param name="list2">List2.</param> private static void FindMatching(List <ExtendedLineInfo> list1, List <ExtendedLineInfo> list2) { int i1 = 0, i2 = 0; foreach (var line in list1) { line.matchingLines.Clear(); line.alreadyUsedInBidirectionalSearch = false; } foreach (var line in list2) { line.matchingLines.Clear(); line.alreadyUsedInBidirectionalSearch = false; } while (i1 < list1.Count) { int i2_reset = i2; while (i2 < list2.Count) { // node2 does not overlap with node1? Then proceed with next node1. if (list1[i1].EndTime < list2[i2].StartTime) { break; } // node1 and node2 overlap! if (UtilsCommon.OverlappingScore(list1[i1], list2[i2]) >= 0.4) { list1[i1].matchingLines.AddLast(list2[i2]); list2[i2].matchingLines.AddLast(list1[i1]); } // try combination (node1, next node2) in next inner iteration i2++; } // do node1 and next node1 overlap? Then all node2's we handled in this iteration might // overlap with next node1 -> reset node2 to start of this iteration. if (i1 + 1 != list1.Count && list1[i1 + 1].StartTime <= list1[i1].EndTime) { i2 = i2_reset; } i1++; } /* * foreach(var primaryListLine in primaryList) { * primaryListLine.matchingLines.Clear(); * primaryListLine.alreadyUsedInBidirectionalSearch = false; * * Action<ExtendedLineInfo, ExtendedLineInfo> matchLines = delegate(ExtendedLineInfo thisLine, ExtendedLineInfo secondaryListLine) { * if (UtilsCommon.OverlappingScore(thisLine, secondaryListLine) < 0.4) return; * thisLine.matchingLines.AddLast (secondaryListLine); * }; * * secondaryListCache.DoForOverlapping(primaryListLine, matchLines); * } */ }